# 多阶段构建:整合前端和后端到单个容器 # ==================== 阶段1: 构建前端 ==================== FROM node:22-alpine AS frontend-builder # 安装pnpm RUN npm install -g pnpm # 设置工作目录 WORKDIR /app/web # 复制前端依赖文件 COPY web/package.json web/pnpm-lock.yaml* ./ # 安装依赖 RUN pnpm install --frozen-lockfile # 复制前端源代码 COPY web/src ./src COPY web/public ./public COPY web/next.config.js ./ COPY web/tailwind.config.ts ./ COPY web/postcss.config.js ./ COPY web/tsconfig.json ./ COPY web/next-env.d.ts ./ # 构建前端应用 RUN pnpm build # ==================== 阶段2: 准备后端 ==================== FROM python:3.12-slim AS backend-builder # 设置工作目录 WORKDIR /app # 设置环境变量 ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV TZ=Asia/Shanghai ENV UV_HTTP_TIMEOUT=600 # 安装系统依赖 RUN apt-get update && apt-get install -y \ curl \ gcc \ g++ \ libpq-dev \ postgresql-client \ poppler-utils \ libmagic1 \ && rm -rf /var/lib/apt/lists/* # 设置时区 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 配置 pip 使用国内镜像源 RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 安装uv RUN pip install uv # 复制后端依赖文件(包括README.md,因为pyproject.toml引用了它) COPY backend/pyproject.toml backend/uv.lock ./ COPY backend/README.md* ./ # 安装Python依赖 RUN UV_HTTP_TIMEOUT=600 uv sync --frozen # ==================== 阶段3: 最终镜像 ==================== FROM python:3.12-slim # 设置工作目录 WORKDIR /app # 设置环境变量 ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 ENV TZ=Asia/Shanghai ENV NODE_ENV=production ENV PORT=8001 ENV HOSTNAME=0.0.0.0 # 安装系统依赖(包括 Node.js 用于运行前端) RUN apt-get update && apt-get install -y \ curl \ gcc \ g++ \ libpq-dev \ postgresql-client \ poppler-utils \ libmagic1 \ nodejs \ npm \ supervisor \ && rm -rf /var/lib/apt/lists/* # 设置时区 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 安装uv RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \ pip install uv # 从后端构建阶段复制Python虚拟环境 # uv 会在 /app/.venv 创建虚拟环境 COPY --from=backend-builder /app/.venv /app/.venv # 复制后端代码和依赖文件 COPY backend/pyproject.toml backend/uv.lock ./ COPY backend/src ./src COPY backend/main.py ./ COPY backend/migrations ./migrations COPY backend/scripts ./scripts # 确保使用虚拟环境中的Python ENV PATH="/app/.venv/bin:$PATH" # 从前端构建阶段复制构建产物 COPY --from=frontend-builder /app/web/.next/standalone ./web COPY --from=frontend-builder /app/web/.next/static ./web/.next/static COPY --from=frontend-builder /app/web/public ./web/public # 创建必要的目录 RUN mkdir -p /app/data /app/vector_store /app/uploads /app/logs /app/generated_images && \ chmod 755 /app/data /app/vector_store /app/uploads /app/logs /app/generated_images # 创建supervisor配置文件 RUN mkdir -p /etc/supervisor/conf.d COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf # 创建启动脚本 COPY docker/start.sh /app/start.sh RUN chmod +x /app/start.sh # 暴露端口 EXPOSE 8000 8001 # 健康检查 HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ CMD curl -f http://localhost:8000/health && curl -f http://localhost:8001 || exit 1 # 启动命令 CMD ["/app/start.sh"]