# 階段 1:構建環境 FROM ghcr.io/astral-sh/uv:python3.14-bookworm-slim AS builder # 設置 uv 緩存和編譯環境變量 ENV UV_COMPILE_BYTECODE=1 \ UV_LINK_MODE=copy WORKDIR /app # 利用 Docker 層緩存安裝依賴 # 這裡使用 --mount 綁定 uv.lock 和 pyproject.toml,避免額外的 COPY 動作 RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=uv.lock,target=uv.lock \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --no-install-project --no-dev # 階段 2:運行環境 FROM python:3.14-slim-bookworm # 設置 Python 環境變量 # PYTHONUNBUFFERED=1: 確保日誌直接輸出而不被緩衝 # PYTHONDONTWRITEBYTECODE=1: 不在容器內生成 .pyc 文件 ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PATH="/app/.venv/bin:$PATH" WORKDIR /app # 創建非 root 用戶並設置權限 RUN groupadd -r appuser && useradd -r -g appuser -u 1000 -m appuser && \ mkdir -p /app/models /app/.cache && \ chown -R appuser:appuser /app USER appuser # 從構建階段複製虛擬環境 COPY --from=builder --chown=appuser:appuser /app/.venv /app/.venv # 下載模型 RUN python -c "from huggingface_hub import snapshot_download; \ snapshot_download(repo_id='ynyg/Unified_Prompt_Guard', \ local_dir='/app/models/Unified_Prompt_Guard', \ ignore_patterns=['*.ckpt', '*.pth', '*.git*'])" # 複製應用代碼 (建議先複製代碼再啟動) # 注意:如果項目很大,建議在 .dockerignore 中排除 .venv, .git 等 COPY --chown=appuser:appuser . . # 暴露 FastAPI 默認端口或 Hugging Face Spaces 要求的端口 EXPOSE 7860 # 使用虛擬環境中的 uvicorn 啟動 # 增加 --proxy-headers 處理反向代理(如 Hugging Face 或 Nginx) CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--proxy-headers"]