# ===== 阶段1: 构建前端 ===== FROM node:20-slim AS frontend-builder WORKDIR /build COPY web/frontend/package.json web/frontend/package-lock.json* ./ RUN npm ci || npm install COPY web/frontend/ ./ RUN npm run build # ===== 阶段2: Python 运行时 ===== FROM python:3.12-slim AS runtime # 优先使用腾讯云镜像源加速;不可用时自动回退官方源。 RUN cp /etc/apt/sources.list.d/debian.sources /tmp/debian.sources && \ sed -i 's/deb.debian.org/mirrors.tencentyun.com/g' /etc/apt/sources.list.d/debian.sources && \ (apt-get update -o APT::Update::Error-Mode=any || \ (cp /tmp/debian.sources /etc/apt/sources.list.d/debian.sources && \ apt-get update -o APT::Update::Error-Mode=any)) && \ apt-get install -y --no-install-recommends \ libgl1 \ libglib2.0-0 \ nodejs \ && rm -rf /var/lib/apt/lists/* # 安装 uv:优先腾讯云 PyPI,失败时回退默认 PyPI。 RUN pip install -i https://mirrors.tencentyun.com/pypi/simple uv || pip install uv WORKDIR /app # 先复制依赖文件,利用 Docker 缓存层 COPY pyproject.toml uv.lock* README.md alembic.ini ./ RUN uv venv /app/.venv && \ (UV_INDEX_URL=https://mirrors.tencentyun.com/pypi/simple uv pip install -e . || uv pip install -e .) # 复制项目代码 COPY core/ ./core/ COPY utils/ ./utils/ COPY web/backend/ ./web/backend/ # 复制前端构建产物 COPY --from=frontend-builder /build/dist ./web/frontend/dist # 创建数据和日志目录 RUN mkdir -p /app/data /app/logs # 环境变量 ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV PATH="/app/.venv/bin:$PATH" EXPOSE 8000 # 健康检查 HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1 # 启动命令 CMD ["python", "-m", "uvicorn", "web.backend.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"]