Files
pengxiao ddbb79b9f6 Initial commit: 国土空间规划课程智能体 v1.0
单容器 Docker 架构的国土空间规划课程智能问答系统,集成 FastAPI 后端与 Next.js 前端。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 09:40:18 +08:00

147 lines
3.6 KiB
Docker

# 多阶段构建:整合前端和后端到单个容器
# ==================== 阶段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"]