Files
writer-work-flow/docker-compose.yml
Yaojia Wang 5464539a91 fix(devops): 修复容器化部署面缺口,docker compose 可干净构建
消除 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 清单与正确部署命令。
2026-07-07 05:01:44 +02:00

54 lines
1.7 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

services:
pg:
image: postgres:16-alpine
environment:
POSTGRES_USER: writer
POSTGRES_PASSWORD: writer
POSTGRES_DB: writer
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U writer"]
interval: 5s
timeout: 3s
retries: 10
volumes:
- pgdata:/var/lib/postgresql/data
api:
build:
context: .
dockerfile: apps/api/Dockerfile
environment:
DATABASE_URL: postgresql+asyncpg://writer:writer@pg:5432/writer
DATABASE_URL_SYNC: postgresql+psycopg://writer:writer@pg:5432/writer
APP_ENV: ${APP_ENV:-dev}
LOG_JSON: ${LOG_JSON:-false}
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000,http://127.0.0.1:3000}
# Fernet 加密 keyapi 启动即校验,缺失/非法则拒绝启动。compose 自动读根 .env 覆盖此默认;
# 默认值 = .env.example 的 dev 占位 key保证 `docker compose up` 无 .env 也能起(勿用于生产)。
CREDENTIAL_ENC_KEY: ${CREDENTIAL_ENC_KEY:-cnMpG6QQxJejuDLHTe_S-nq2snoKgXCqWFfsctEHB-4=}
ports:
- "8000:8000"
depends_on:
pg:
condition: service_healthy
web:
build:
context: ./apps/web
# NEXT_PUBLIC_API_BASE 为构建期内联,须经 build arg 传入(见 apps/web/Dockerfile
args:
NEXT_PUBLIC_API_BASE: ${NEXT_PUBLIC_API_BASE:-http://localhost:8000}
environment:
NEXT_PUBLIC_API_BASE: ${NEXT_PUBLIC_API_BASE:-http://localhost:8000}
# RSC 服务端取数走容器内网直连 api否则回退 localhost:8000 打不到 api 容器)。
API_BASE_INTERNAL: http://api:8000
ports:
- "3000:3000"
depends_on:
- api
volumes:
pgdata: