# 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 不保證有。改用 curl(python: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"]