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 加密 key:api 启动即校验,缺失/非法则拒绝启动。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: