# 多阶段构建(G1 多阶段强制规则) # Stage 1: builder - 安装依赖 + 生成 proto 代码 # Stage 2: runtime - 精简运行时镜像 # 用法:docker build -t edu/ai:latest -f services/ai/Dockerfile . # === Stage 1: builder === FROM python:3.12-slim AS builder WORKDIR /app # 安装 uv(快速依赖管理) RUN pip install --no-cache-dir uv # 复制 workspace 根配置 + shared-py 包(uv workspace 依赖) COPY pyproject.toml uv.lock* ./ COPY packages/shared-py ./packages/shared-py # 复制 ai 服务配置 COPY services/ai/pyproject.toml ./services/ai/pyproject.toml # 安装生产依赖(含 dev 依赖用于生成 proto) WORKDIR /app/services/ai RUN uv sync --all-extras # 复制源码 COPY services/ai/src ./src # 生成 gRPC 代码(如果 proto_gen 不存在或需更新) RUN uv run python -m grpc_tools.protoc \ -I /app/proto \ --python_out=src/ai/proto_gen \ --grpc_python_out=src/ai/proto_gen \ /app/proto/ai.proto || echo "proto gen skipped (no proto dir)" # === Stage 2: runtime === FROM python:3.12-slim AS runtime WORKDIR /app # 安装运行时系统依赖(curl 用于健康检查) RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ && rm -rf /var/lib/apt/lists/* # 从 builder 复制虚拟环境(uv workspace 在根目录创建 .venv) COPY --from=builder /app/.venv /app/.venv # 从 builder 复制源码(含生成的 proto 代码) COPY --from=builder /app/services/ai/src /app/src # 环境变量 ENV PATH="/app/.venv/bin:$PATH" \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONPATH="/app/src" # 暴露端口(HTTP 3008 + gRPC 50058) EXPOSE 3008 50058 # 健康检查(HTTP /healthz) HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD curl -f http://localhost:3008/healthz || exit 1 # 启动命令(uvicorn + gRPC server 由 main.py 内部启动) CMD ["python", "-m", "uvicorn", "ai.main:app", "--host", "0.0.0.0", "--port", "3008"]