250d4355b9
P5-prep Task 1(docs/plans/2026-09-21-P5-准备件.md): - docker/server.Dockerfile:单镜像 photo-live-server 多角色(api-cn/api-ov/ worker/sync/migrate-deploy/seed-admin,entrypoint.sh 分发;migrate-deploy 支持 cn|ov|all 区域参数)。三阶段:全量 install(锁文件冻结)→ prisma generate 双库 + 逐包构建;--prod 依赖层;runtime=node:20-alpine+openssl/curl + 全局 prisma@5.22.0(对齐锁文件)+ 双库 client 镜像内重建(db-cn 落 pnpm store .prisma、db-ov 落包内 generated/)。sharp 走 musl 预编译验证通过。 - docker/web.Dockerfile + infra/deploy/nginx.conf.template:photo-live-web (nginx:alpine + envsubst 模板)。viewer(/,history 回退) + admin(/admin/, hash 路由) + /v1 反代 API_UPSTREAM(含 /v1/realtime WS 升级)+ /assets/、/admin/assets/、/embed/v1/ immutable 长缓存(admin assets 的 alias 前缀剥除坑已实测修复)。VITE_* 为构建期参数(VIEWER_BASE/ EMBED_ORIGIN 随域名构建传入)。 - infra/deploy/docker-compose.cn.yml / -ov.yml:cn=api-cn+worker+sync+web, ov=api-ov+web-ov(核实架构:sync 仅 cn 侧,inbox/emergency 内嵌 api-ov, 无 ov 侧 sync 进程);健康检查 /v1/health、unless-stopped、json-file 10m×3、外部 1panel-network 复用 1Panel MySQL/Redis、SERVER_IMAGE/ WEB_IMAGE 环境变量化镜像 tag(回滚杠杆)。 - .env.production.example-cn/-ov:生产变量全量清单(cn 25 键/ov 24 键, DB/Redis/OSS/SYNC/AUTH/限速/域名分组注释,源自 services+packages process.env 全量审计);.gitignore 放行 example,真实 .env.production-* 永不入库。 - infra/deploy/README-1Panel.md:镜像导入双路径(save tar 导入 / 仓库 pull)、 MySQL 建库授权 SQL(utf8mb4_0900_bin,<8.0.30 回退 utf8mb4_bin——D12)、 Redis 连接、1Panel 编排、OpenResty 反代+证书、migrate-deploy 一次性容器、 首次部署顺序(DB→迁移→ov 栈→cn 栈→seed→冒烟)。 - 根 package.json pnpm.onlyBuiltDependencies 增补 sharp/prisma/@prisma/ engines/@prisma/client(镜像构建所需 install 脚本白名单)。 本地验证:两镜像构建成功(server 988MB / web 97.7MB);compose config 校验 通过;server 镜像内逐服务 require(sharp/argon2/双 Prisma client/bullmq/ ioredis)与双引擎 so.node、migrate-deploy 角色、无 .env 泄漏均实测;web 镜像 容器实测路由(viewer 回退/admin 子路径/assets 与 embed immutable/WS 代理路径 502 语义)全通过。未起真实栈(无真实 DB,符合准备件边界)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
89 lines
3.3 KiB
YAML
89 lines
3.3 KiB
YAML
# 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", "curl", "-fs", "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
|