docs(ci): 记录生产流水线决策与运行手册

固化 Tag 发布策略、Runner 信任边界、Secret 位置、数据库回滚限制,以及 Runner 安装、发布、验证和故障恢复步骤。
This commit is contained in:
2026-07-17 12:41:47 +08:00
parent 745811cc6d
commit db85487b73
3 changed files with 145 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
# ADR-001: 使用仓库级 Runner 和不可变镜像发布生产环境
## 状态
Accepted
## 日期
2026-07-17
## 背景
AI Gateway 已通过独立部署仓库和 Docker Compose 手工运行在 `110.42.51.33`,公共入口是 `https://ai.51easyai.com`。同一服务器还运行认证中心、K3s 和其他 EasyAI 服务,磁盘空间有限。Gitea 1.22 的 host Runner 已知不能可靠启动第二个依赖 Job,也不完整支持 GitHub Actions 的 `environment``permissions``concurrency` 语义。
生产发布必须满足:源码可追溯、数据库迁移前有备份、失败可恢复上一应用版本、Secret 不进入仓库或流水线日志,并且不能让普通分支自动修改生产环境。
## 决策
-`BCAI/easyai-ai-gateway` 注册独立、仓库级 host Runner。它不与认证中心 Runner 共享身份、状态目录或任务标签。
- Pull Request 和 `main` Push 执行相同质量门禁与镜像构建;只有符合 `vMAJOR.MINOR.PATCH` 形式、且目标提交属于 `main` 历史的 Tag 才发布生产。
- API/Web 镜像使用完整 Git SHA 作为运行时 Tag。语义版本 Tag 只是发布授权信号,不作为可变镜像标识。
- 验证和发布处于同一个 Runner Job。这样部署只使用已通过全部门禁的同一 checkout,并规避当前 Gitea 版本的依赖 Job 领取问题。
- Runner 使用专属 Buildx builder,缓存上限为 2 GB。服务器 root 现有的阿里云 Registry 凭据只由固定发布助手使用,不复制到 Gitea Secret。
- 发布助手在迁移前生成 PostgreSQL custom-format 备份并验证目录;保留最近 5 份。应用健康检查失败时恢复上一组 API/Web 镜像。
- 数据库迁移必须保持向后兼容。自动回滚只覆盖应用镜像;数据库恢复需要人工确认,避免覆盖失败发布后产生的有效写入。
- Gitea Runner 的 Docker 权限等价于宿主机 root 权限。因此只允许受信任的仓库维护者触发该 Runner,来自 Fork 的 Pull Request 必须先经维护者批准。
## 备选方案
### 复用认证中心 Runner
拒绝。现有 Runner 是认证中心仓库级身份,扩大为组织级 Runner 会让更多仓库获得同一 Docker/root 信任边界。
### 由 Runner 保存 SSH 或 Registry Secret
拒绝。Runner 已位于目标服务器,绕回 SSH 会增加长期凭据;复制 Registry Secret 也会扩大暴露面。固定 root helper 可以复用服务器现有登录状态。
### `main` 通过后直接发布生产
拒绝。`ai.51easyai.com` 是生产入口。语义版本 Tag 提供明确的发布授权点,同时仍保留自动化与可审计性。
### 只依赖 `latest`
拒绝。`latest` 无法证明运行中的容器对应哪个源码提交,也不能可靠选择回滚版本。
## 影响
- 日常合并不会自动改变生产;创建并推送版本 Tag 才会部署。
- 首次启用 CD 时需要在服务器捕获当前运行镜像作为 bootstrap 回滚基线。
- 发布前必须确保数据库迁移对上一应用版本保持兼容。
- 如果未来增加不受信任的贡献者,应把 CI 构建迁移到隔离的 rootless Runner,并保留独立的受保护部署 Runner。