Files
photo-live/infra/deploy/docker-compose.cn.yml
T
浅念 c26d6b9a73 fix(deploy): review fixes — smoke photoId field, web healthcheck wget, outbox table name, cdn key shape
Reviewer findings on p5-prep batch:
1. BLOCKING: prod-smoke.sh visibility grep used "id" but API items
   serialize photoId (cn public.service / ov public-ov.service) — every
   healthy deployment would false-FAIL release gate ④. 4 sites fixed.
2. web/web-ov healthchecks used curl on nginx:alpine (absent) → perpetual
   false-unhealthy; switched to busybox wget.
3. RUNBOOK rollback rule cited nonexistent sync_outbox → outbox_events.
4. cdn-checklist invalidation sample key shape aligned to actual
   variantsObjectKey layout (.../albums/{albumId}/variants/{photoId}/{version}/{variant}.jpg).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-21 02:03:44 +08:00

89 lines
3.3 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.
# infra/deploy/docker-compose.cn.yml —— 国内(cn)生产编排(P5-prep Task 1)。
# 角色:api-cn(写路径 API)/ worker(sharp 变体流水线 + 发布事务 outbox)/
# sync(outbox→ov 推送 + 对账 + 统计回传,双库直连)/ web(nginx 网关)。
# 架构核实:sync 是独立进程跑在 cn 侧(services/sync/src/main.ts 双库连接);
# ov 侧无任何 sync 进程(inbox 内嵌 api-ov,见 docker-compose-ov.yml)。
#
# 使用(1Panel 容器→编排→新建编排,或 docker compose -f 本文件 up -d):
# 1. 同目录放 .env.production-cn(模板见仓库根 .env.production.example-cn)。
# 2. 镜像已导入(README-1Panel.md §1);SERVER_IMAGE/WEB_IMAGE 可用环境变量
# 覆盖 tag(回滚 = 指回旧 tag 后 up -d,见 RUNBOOK.md)。
# 3. 网络默认挂外部 1panel-network 以便用容器名直连 1Panel 的 MySQL/Redis;
# 若你的 1Panel 网络名不同,或打算用宿主机 IP + 端口连接,把下方 networks
# 整段换成普通桥接网络(photo-net: {})并同步改 .env 里的连接串 host。
#
# 首次部署顺序(迁移先于 API):README-1Panel.md §7。
name: photo-live-cn
x-server-image: &server-image ${SERVER_IMAGE:-photo-live-server:latest}
x-logging: &default-logging
driver: json-file
options: { max-size: "10m", max-file: "3" }
services:
api-cn:
image: *server-image
command: ["api-cn"]
init: true
env_file: .env.production-cn
environment:
PORT: "8080" # 容器内固定;对外经 web 反代或 OpenResty
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-fs", "http://127.0.0.1:8080/v1/health"]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
logging: *default-logging
networks: [photo-net]
worker:
image: *server-image
command: ["worker"]
init: true
env_file: .env.production-cn
# 无 HTTP 端口:健康面由 restart 策略 + 日志监控承担(RUNBOOK.md 故障速查)。
restart: unless-stopped
logging: *default-logging
networks: [photo-net]
sync:
image: *server-image
command: ["sync"]
init: true
env_file: .env.production-cn
# 需要额外可达:OV_API_URL(公网域名)与 DATABASE_URL_OV(ov MySQL,跨地域)。
restart: unless-stopped
logging: *default-logging
networks: [photo-net]
web:
image: ${WEB_IMAGE:-photo-live-web:latest}
init: true
environment:
API_UPSTREAM: http://api-cn:8080 # /v1 反代目标(含 WS /v1/realtime)
ports:
# 只绑本机回环:1Panel OpenResty(同宿主机)反代到 127.0.0.1:8088;
# OpenResty 在其它机器时改为 "8088:80" 并配防火墙白名单。
- "127.0.0.1:8088:80"
restart: unless-stopped
depends_on:
api-cn: { condition: service_healthy }
healthcheck:
test: ["CMD", "wget", "-qO", "/dev/null", "http://127.0.0.1/"]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s
logging: *default-logging
networks: [photo-net]
networks:
photo-net:
# 复用 1Panel 应用网络(其名通常为 1panel-network):容器名互通 MySQL/Redis。
# 若网络名不同:name 改实际名。若走宿主机 IP 连接:整段替换为 `photo-net: {}`。
name: 1panel-network
external: true