3.1 KiB
3.1 KiB
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 和
mainPush 执行相同质量门禁与镜像构建;只有符合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。