Files
chorus/docs/10-deployment-and-operations.md
T

6.8 KiB
Raw Blame History

generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Deployment-and-Operations wiki_url: https://git.ilapage.cn/OPC/chorus/wiki/Deployment-and-Operations.- wiki_revision: 040f4c2c3e16def91fe612fa09cf0a6aa7288445 synchronized_at: 2026-08-20T07:01:36Z

部署与运维

本页用途

本页定义 chorus 常驻服务的生产部署基线。当前尚无产品代码和真实生产环境,命令是后续实现必须满足的运维契约;域名、容量、保留期和阈值在首发工单确认后补充,不能由 Agent 猜测。

安全边界

  • 生产只部署已审核制品和 migrations/;不从 D:\github\goadmin 构建,不运行 AutoMigrate。
  • dev-tools 生成路由、/gen/todb 和写源码能力不得注册或被 nginx 代理;仅隐藏菜单不合格。
  • DSN、会话密钥、Provider 主密钥/key ring、TLS 私钥只来自受控环境文件或密钥管理系统,权限最小化,不写入 Git/Wiki/日志。
  • 原图、结果和缩略图保存在受保护目录,通过 portal 鉴权读取,不由 nginx 直接暴露。
  • 数据迁移、回退、删除、清理和密钥轮换均是高风险操作,必须有工单、备份和人工确认。

服务概览

Internet
  → nginx/TLS
      → chorus-portal 127.0.0.1:8080(页面、HTMX、JSON、MVP 内嵌 worker)
      → chorus-admin  127.0.0.1:8081(MVP-1)
      → /admin-ui 静态构建产物(MVP-1)
portal/admin → MySQL 8.0
portal worker → Provider(安全 DialContext)
portal → /var/lib/chorus/storage(或后续对象存储适配)
项目 基线
运行账号 独立无登录 chorus 用户
制品目录 /opt/chorus/releases/<commit>/,/opt/chorus/current 指向当前版本
配置 /etc/chorus/chorus.env,仅运行账号可读
持久数据 /var/lib/chorus/storage,不随版本目录切换
日志 journald 或平台日志;结构化且脱敏
进程托管 systemd:chorus-portal.service、chorus-admin.service
数据库 MySQL 8.0,独立最小权限账号
构建 CI 使用 Go 1.26.5;admin-ui 使用 Node >=22 + pnpm 9.15.1

配置与凭据

配置 用途 敏感
CHORUS_ENV=production 启用生产安全门禁 否
CHORUS_DSN MySQL 是
CHORUS_MASTER_KEY / key ring Provider Key 加解密与轮换 是
CHORUS_SESSION_KEY portal 会话 是
CHORUS_STORAGE_ROOT 生成物目录 否
上游/存储超时、lease、worker 数 执行与优雅退出 否
上传和限流阈值 数量、大小、MIME、像素、请求频率 否
保留期与磁盘告警 清理和容量保护 否

生产启动必须校验必需配置、密钥长度/key_id、目录权限、超时与 lease 关系;缺失或不安全时 fail closed。CHORUS_ENV=production 下若检测到 AutoMigrate 或 dev-tools 注册必须拒绝启动。

制品构建

在干净 CI 环境按固定提交来源导入后的 chorus 代码构建:

go version
go test ./...
go vet ./...
go build -trimpath -o dist/chorus-portal ./portal
go build -trimpath -o dist/chorus-admin ./admin
corepack pnpm --dir admin-ui install --frozen-lockfile
corepack pnpm --dir admin-ui build:prod

MVP-0 没有 admin/admin-ui 时跳过对应命令并在发布记录说明。制品记录 chorus commit、Go module 校验、admin-ui lockfile 和固定 go-admin 来源提交。

首次部署与升级顺序

  1. 记录当前/目标 commit、迁移版本、制品校验值和回退条件。
  2. 备份 MySQL,并验证备份可读取;确认持久存储快照/备份策略。
  3. 把制品解压到新的 release 目录,不原位覆盖当前版本。
  4. 用相同 MySQL 8 版本的隔离库执行全部 migration up/down/up 验证。
  5. 停止取新任务并等待在途 worker 到优雅退出期限;旧 worker 未结束时不得启动会竞争同一租约的错误版本。
  6. 在生产执行 migrate ... up;检查版本,禁止任何 AutoMigrate。
  7. 原子切换 current,启动/重启 portal 和 admin。
  8. 执行健康、就绪、登录、提交 mock/受控测试和权限检查。
  9. 验证生产访问 dev-tools 路径为 404/未注册,并核对路由清单。
  10. 观察错误率、租约过期、磁盘和数据库连接;满足观察窗口后完成发布记录。

健康与就绪

应用必须提供:

  • /healthz:进程存活,不依赖上游;
  • /readyz:必需配置有效、MySQL 可用、迁移版本匹配、存储可写、生产 dev-tools 未注册;
  • admin 健康路径不得泄露版本、DSN、路由或密钥。
systemctl status chorus-portal
curl --fail http://127.0.0.1:8080/healthz
curl --fail http://127.0.0.1:8080/readyz
journalctl -u chorus-portal -n 100 --no-pager

MVP-1 同样检查 admin 8081。外部检查经 TLS/nginx 访问,不把内部端口暴露公网。

worker 优雅退出

  • 收到 TERM 后先停止认领新任务;
  • 在途任务只在 lease_token 仍有效时提交;
  • systemd 的停止等待时间大于应用优雅退出期限;
  • 到期未完成时退出,让租约自然过期,新 worker 原子重领;
  • 不把 running 改回 pending,不无条件标 failed,不删除其他 worker 文件。

存储、备份与监控

必须备份 MySQL 和仍在保留期内的生成物元数据/文件,并定期做恢复演练。至少监控:

  • MySQL 连接、慢查询、迁移版本;
  • pending 数/最老等待时间、running 租约过期数、失败率;
  • Provider 429/5xx/超时和熔断状态;
  • 存储总量、可用空间、临时文件增长、缩略图失败;
  • 登录失败/节流、SSRF 拦截和越权拒绝;
  • portal/admin 健康与重启次数。

保留期、备份频率、RPO/RTO、磁盘阈值尚未确认,是生产上线门禁。清理任务不得在确认前启用。

回滚

  • 优先使用向后兼容迁移并回滚二进制;先停止新任务,再切回上一 release,重启并执行健康检查。
  • 不能仅通过切回代码撤销数据库变更。需要 down 或恢复备份时先评估数据丢失,取得人工确认。
  • 若新版本已写入旧版本无法识别的数据,停止回滚并采用前滚修复或已演练的备份恢复方案。
  • 回滚后检查 migration version、陈旧 worker CAS、任务重复、文件一致性和 dev-tools 路由。
  • 每次真实发布前至少在隔离环境演练相同升级与回滚步骤。

已知限制

  • 尚未完成真实 Linux/systemd/nginx 部署、备份恢复和回滚演练;
  • 高可用、多机 worker、对象存储和滚动升级尚未设计;
  • 生产域名、TLS、容量、保留期、告警、RPO/RTO 和具体超时/lease 阈值待首发部署工单确认;
  • 在这些门禁完成前,本页不能作为“已验证可上线”的证据。