nv / Dockerfile
99i's picture
Update Dockerfile
baff988 verified
# MuMuAINovel 单 Dockerfile 部署
# 从 GitHub 拉取项目,内联所有构建步骤,仅暴露 7860 端口
FROM python:3.11-slim AS backend-builder
WORKDIR /build
# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
postgresql-client \
git \
&& rm -rf /var/lib/apt/lists/*
# 从 GitHub 克隆项目
RUN git clone --depth 1 https://github.com/xiamuceer-j/MuMuAINovel.git project
# 安装 Python 依赖
WORKDIR /build/project/backend
RUN pip install --no-cache-dir -r requirements.txt
# 预下载 Embedding 模型
ENV SENTENCE_TRANSFORMERS_HOME=/app/embedding
RUN mkdir -p /app/embedding
RUN python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')"
# ==================== Frontend Build Stage ====================
FROM node:20-slim AS frontend-builder
WORKDIR /build
# 从 GitHub 克隆项目(前端构建需要)
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
RUN git clone --depth 1 https://github.com/xiamuceer-j/MuMuAINovel.git project
WORKDIR /build/project/frontend
RUN npm install
# 修改 vite.config.ts 确保输出到 dist 目录
RUN sed -i "s|outDir:.*|outDir: 'dist',|g" vite.config.ts || true
RUN npm run build
# 确认 dist 目录存在
RUN ls -la /build/project/frontend/
# ==================== Final Runtime Image ====================
FROM python:3.11-slim
WORKDIR /app
# 安装运行时依赖
RUN apt-get update && apt-get install -y \
netcat-traditional \
git \
&& rm -rf /var/lib/apt/lists/*
# 创建必要的目录
RUN mkdir -p /app/data /app/logs /app/storage/generated_covers /app/embedding /app/backend/static /app/scripts
# 从构建阶段复制 Python 依赖
COPY --from=backend-builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=backend-builder /usr/local/bin/alembic /usr/local/bin/alembic
COPY --from=backend-builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn
# 复制预下载的模型
COPY --from=backend-builder /app/embedding /app/embedding
# 从 GitHub 克隆后端代码
RUN git clone --depth 1 https://github.com/xiamuceer-j/MuMuAINovel.git /tmp/project
# 复制所有后端文件,包括 alembic.ini
RUN cp -r /tmp/project/backend/. /app/backend/
# 复制 Alembic 迁移配置和脚本(PostgreSQL)
COPY --from=backend-builder /build/project/backend/alembic-postgres.ini ./alembic.ini
COPY --from=backend-builder /build/project/backend/alembic/postgres ./alembic
COPY --from=backend-builder /build/project/backend/scripts/entrypoint.sh /app/entrypoint.sh
COPY --from=backend-builder /build/project/backend/scripts/migrate.py ./scripts/migrate.py
# 复制前端构建产物
COPY --from=frontend-builder /build/project/frontend/dist /app/backend/static
# 设置执行权限
RUN chmod +x /app/entrypoint.sh
COPY ca.pem /app/certs/ca.pem
# 设置环境变量
ENV PYTHONUNBUFFERED=1
ENV APP_HOST=0.0.0.0
ENV APP_PORT=7860
ENV SSL_CERT_FILE="/app/certs/ca.pem"
# 设置全局 SSL 证书环境变量,很多 Python 库会读取这个
ENV REQUESTS_CA_BUNDLE="/app/certs/ca.pem"
ENV NODE_EXTRA_CA_CERTS="/app/certs/ca.pem"
ENV SENTENCE_TRANSFORMERS_HOME=/app/embedding
ENV TRANSFORMERS_OFFLINE=1
ENV HF_DATASETS_OFFLINE=1
ENV HF_HUB_OFFLINE=1
# 创建工作目录
WORKDIR /app/backend
# 【高级修复】尝试自动注入 SSL 配置到数据库连接代码
# 查找常见的数据库初始化文件并尝试注入 ssl 参数
# 注意:这取决于项目具体结构,这里做一个通用的尝试
# RUN if grep -q "asyncpg.create_pool" app/core/database.py 2>/dev/null; then \
# sed -i "s/ssl=True/ssl={'ca': '\/app\/certs\/ca.pem'}/g" app/core/database.py; \
# sed -i "s/sslmode=require/sslmode=require&\&sslrootcert=\/app\/certs\/ca.pem/g" app/core/database.py; \
# fi || true
EXPOSE 7860
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:7860/health')" || exit 1
# 启动命令:使用 entrypoint.sh 脚本处理迁移并启动服务
CMD ["/app/entrypoint.sh"]