easyai-ai-gateway/docs/decisions/001-production-cicd.md
chengcheng db85487b73 docs(ci): 记录生产流水线决策与运行手册
固化 Tag 发布策略、Runner 信任边界、Secret 位置、数据库回滚限制,以及 Runner 安装、发布、验证和故障恢复步骤。
2026-07-17 12:41:47 +08:00

3.1 KiB
Raw Blame History

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 的 environmentpermissionsconcurrency 语义。

生产发布必须满足源码可追溯、数据库迁移前有备份、失败可恢复上一应用版本、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。