# 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"]