消除 DEPLOYMENT.md §1.5 列出的 6 个「照抄即部署」缺口(仅动部署面文件,不改应用源码):
1. apps/api/Dockerfile 补 `COPY alembic.ini ./`,容器内可直接 alembic upgrade head。
2. base compose api 注入 CREDENTIAL_ENC_KEY(${VAR:-dev 占位},自动读根 .env 覆盖)+
APP_ENV/LOG_JSON/CORS_ORIGINS,无 .env 也能起,不再因缺 Fernet key 启动失败。
3. base compose web 设 API_BASE_INTERNAL=http://api:8000,RSC 直连 api 容器。
4. web Dockerfile 加 ARG/ENV NEXT_PUBLIC_API_BASE(默认 localhost:8000),compose
web.build.args 传入,构建期可注入公网 API 基址。
5. api/web Dockerfile 内置 HEALTHCHECK(api 用 urllib 打 /health、web 用 node 打 /)。
6. 新增 docker-compose.prod.yml 覆盖层做生产加固:pg 强口令 ${POSTGRES_PASSWORD}、
pg 仅绑 127.0.0.1、APP_ENV=prod、LOG_JSON=true、密钥/连接串/CORS/公网 API 全从
env 且必填(:? 缺失拒起)、restart: unless-stopped。base 保持 dev 便利不破坏。
附带修复:web Dockerfile 在 install 前补 COPY pnpm-workspace.yaml,使容器内 install
看到 minimumReleaseAgeExclude/onlyBuiltDependencies,避免误拒 @xyflow 等近期发布依赖;
新增 .dockerignore(根 + apps/web)排除宿主 node_modules/.next/.venv 等,避免平台原生
二进制经 COPY . . 覆盖容器版导致 next build 失败,并加速构建上下文、保证可复现。
验证:docker compose config(base)与 prod 合并 config 均通过;docker compose build
两镜像均成功(api 378MB / web 296MB);自定义 NEXT_PUBLIC_API_BASE 已确认内联进前端
bundle。DEPLOYMENT.md §1.5 回写为「已修复」并补 §2.6 生产 env 清单与正确部署命令。
41 lines
2.1 KiB
YAML
41 lines
2.1 KiB
YAML
# 生产加固覆盖层 —— 与 base 叠加使用(base 保持 dev 便利,本文件收紧安全):
|
||
# docker compose -f docker-compose.yml -f docker-compose.prod.yml build
|
||
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||
#
|
||
# 需在宿主机 .env(chmod 600,勿入库)或环境变量提供以下必填项(缺失即拒绝 up / config 报错):
|
||
# POSTGRES_PASSWORD —— pg 强随机口令(替换 base 的弱口令 writer/writer)
|
||
# CREDENTIAL_ENC_KEY —— Fernet key(生产新生成,勿用 .env.example 占位值)
|
||
# CORS_ORIGINS —— 前端真实来源,逗号分隔,禁通配 *
|
||
# NEXT_PUBLIC_API_BASE—— 浏览器可达的公网 API 基址(构建期内联进 web bundle)
|
||
services:
|
||
pg:
|
||
environment:
|
||
POSTGRES_USER: writer
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD 必填(生产强口令,勿用 base 弱口令)}
|
||
POSTGRES_DB: writer
|
||
# 不对公网暴露:仅绑本机回环(供宿主机跑迁移)。彻底隔离可整段删掉只走 compose 内网。
|
||
ports:
|
||
- "127.0.0.1:5432:5432"
|
||
restart: unless-stopped
|
||
|
||
api:
|
||
environment:
|
||
DATABASE_URL: postgresql+asyncpg://writer:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD 必填}@pg:5432/writer
|
||
DATABASE_URL_SYNC: postgresql+psycopg://writer:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD 必填}@pg:5432/writer
|
||
APP_ENV: prod
|
||
LOG_JSON: "true"
|
||
CREDENTIAL_ENC_KEY: ${CREDENTIAL_ENC_KEY:?CREDENTIAL_ENC_KEY 必填(生产 Fernet key,勿用占位值)}
|
||
CORS_ORIGINS: ${CORS_ORIGINS:?CORS_ORIGINS 必填(前端真实来源,逗号分隔,禁通配)}
|
||
restart: unless-stopped
|
||
|
||
web:
|
||
build:
|
||
context: ./apps/web
|
||
args:
|
||
# 构建期内联:生产须指向浏览器可达的公网 API(通常反代后的 https 域名)。
|
||
NEXT_PUBLIC_API_BASE: ${NEXT_PUBLIC_API_BASE:?NEXT_PUBLIC_API_BASE 必填(浏览器可达的公网 API 基址)}
|
||
environment:
|
||
NEXT_PUBLIC_API_BASE: ${NEXT_PUBLIC_API_BASE:?NEXT_PUBLIC_API_BASE 必填}
|
||
API_BASE_INTERNAL: http://api:8000
|
||
restart: unless-stopped
|