Files
awoooi/apps/api/Dockerfile
Your Name 13e51802fe feat(awooop): Phase 0 全 ADR + Phase 1 control plane schema(含 critic 四項修正)
## Phase 0(文件層,全部 Accepted)
- ADR-106/107:AwoooP 平台架構 + 儲存策略
- ADR-111~118:Bootstrap → RLS 七項核心 ADR
- ADR-119~124:SAGA → Singleton Decomposition 六項 ADR
- ADR-UI-01~04:Operator Console 四個 UI ADR

## Phase 1(DB schema + migration)
- awooop_phase1_control_plane_2026-05-04.sql:7 張新表 + trigger + RLS
  - Step 1:三角色(platform_admin/migration BYPASSRLS,awooop_app 受 RLS)
  - Step 13:GRANT awooop_app 最小權限(7 條)
  - Step 14:RLS fail-closed,移除 __platform__ 後門
- awooop_phase1_batch1_rls_2026-05-04.sql:高流量四表三步式 ADD COLUMN
- awooop_phase1_batch1_backfill.py:SKIP LOCKED 分批回填腳本
- awooop_models.py:7 個 SQLAlchemy 2.x models

## Critic 修正(4 Critical + 3 Major)
- C-1:ADD CONSTRAINT IF NOT EXISTS → DO 塊 + pg_constraint 查詢
- C-2:__mapper_args__ 字串 list → primary_key=True on mapped_column
- C-3:__platform__ RLS 後門 → 全移除,改用 BYPASSRLS role
- C-4:awooop_app role 從未建立 → Step 1 + 7 條 GRANT
- M-1:active_pointer_guard SECURITY DEFINER(FORCE RLS 跨租戶保護)
- M-2:pg_partman create_parent 加冪等防護
- M-3:immutability trigger 新增身份欄位保護(project_id/family/contract_id)

## Task 1.2 修補
- agent_loader.py:硬編碼 Mac 路徑 → AGENTS_DIR 環境變數
- Dockerfile:補 COPY .claude/agents/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 13:37:11 +08:00

92 lines
3.9 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AWOOOI API - Production Dockerfile
# Phase 6.4i: 支援 monorepo 本地 packages (lewooogo-brain, lewooogo-data)
#
# 使用方式 (從 monorepo 根目錄):
# docker build -f apps/api/Dockerfile -t awoooi-api:v1.0.0 .
#
# 注意: 必須從 monorepo 根目錄執行,否則無法存取 packages/
# syntax=docker/dockerfile:1
# 首席架構師 Review C1 (2026-04-05 Claude Code): BuildKit inline cache 需要 syntax 宣告
# BUILDKIT_INLINE_CACHE=1 才能真正把 cache metadata 寫入 image
ARG BUILDKIT_INLINE_CACHE=0
FROM python:3.11-slim AS builder
WORKDIR /app
# Install uv (固定版本,禁止 :latest)
COPY --from=ghcr.io/astral-sh/uv:0.6.9 /uv /bin/uv
# Phase 6.4i: 複製本地 packages 到 Docker context
COPY packages/lewooogo-data/ /packages/lewooogo-data/
COPY packages/lewooogo-brain/ /packages/lewooogo-brain/
# 複製 API 依賴文件(只複製 metadata不含 src/
COPY apps/api/pyproject.toml apps/api/README.md ./
# 首席架構師 Review C3 (2026-04-05 Claude Code):
# 原始問題COPY src/ 在 pip install 之前src 任何變更都讓 deps layer 失效
# 修復:先安裝 local packages再用 --no-build-isolation 只安裝 pyproject 的依賴項
# (不 build wheel不需要 src/src/ 在之後才 COPY
# 注意:--no-sources 不被 uv 支援,改用建立 stub src 讓 hatchling 可以解析
RUN mkdir -p src/awoooi_api && \
touch src/awoooi_api/__init__.py && \
uv pip install --system --no-cache /packages/lewooogo-data && \
uv pip install --system --no-cache /packages/lewooogo-brain && \
uv pip install --system --no-cache .
# deps 安裝完後才複製真正的 src使 deps layer 可 cache
COPY apps/api/src/ ./src/
# Production stage
FROM python:3.11-slim
WORKDIR /app
# Copy installed packages from builder
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin
# 2026-04-01 ogt: CACHE_BUST 強制失效 src/ 和 models.json 層
# deps 層 (pip install) 仍可 cache代碼/配置變更必須重建
ARG CACHE_BUST=none
COPY apps/api/src/ ./src/
COPY apps/api/models.json ./models.json
# 2026-04-09 ogt: 規則引擎配置 — alert_rule_engine.py 從此檔載入規則
COPY apps/api/alert_rules.yaml ./alert_rules.yaml
# 2026-04-10 Claude Sonnet 4.6: drift_detector 需要 k8s/ YAML 做 Git state 比對
COPY k8s/ ./k8s/
# 2026-04-10 Claude Sonnet 4.6: RAG 知識庫索引來源 (ADR-067 Phase 33)
COPY docs/ ./docs/
COPY .agents/skills/ ./.agents/skills/
# 2026-05-04 Claude Sonnet 4.6 (Task 1.2): hermes agent_loader 的 system prompt 來源
# agent_loader.py 預設讀 /app/.claude/agents/,對應 K8s AGENTS_DIR 環境變數
COPY .claude/agents/ ./.claude/agents/
# 2026-04-12 ogt (ADR-073 P2-1): CronJob 腳本 — 獨立腳本取代 inline Python
COPY scripts/ ./scripts/
# Install openssh-client + curl — SSH_COMMAND Playbook + healthcheck
# Install kubectl — drift_detector 需要 kubectl 讀取 K8s 實際狀態
# (2026-04-09 Claude Sonnet 4.6 Asia/Taipei, Bug #6 修正 — python:3.11-slim 無 openssh-client)
# (2026-04-10 Claude Sonnet 4.6 Asia/Taipei: drift kubectl_error — No such file or directory: 'kubectl')
RUN apt-get update && apt-get install -y --no-install-recommends openssh-client curl && \
curl -LO "https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl" && \
chmod +x kubectl && mv kubectl /usr/local/bin/kubectl && \
rm -rf /var/lib/apt/lists/*
# Create non-root user
RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
USER appuser
# Expose port
EXPOSE 8000
# 首席架構師 Review S3 (2026-04-05 Claude Code):
# httpx 可能只在 dev deps生產 image 不保證有。改用 curlpython:3.11-slim 內建)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -sf http://localhost:8000/api/v1/health || exit 1
# Run application
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]