- 删除 6 个分散 workflow(ci-ts/ci-go/ci-proto/ci-py/docker/deploy) - 合并为单个 ci.yml:3 个 quality job 并行 + deploy job 串行 - 全部使用官方镜像(node:22-alpine/golang:1.22-alpine/bufbuild/buf/docker:25-git) - deploy job 用 DooD 模式挂载 /var/run/docker.sock - docker-compose.deploy.yml 改用 build: 替代 image:(no-push) - 新增 docker-compose.tools.yml 一次性预拉所有 CI 镜像 - 支持 workflow_dispatch 指定 commit_sha 回滚 - 更新 project_rules §15 与 cicd-runbook.md 为 no-push 模式 - 新增设计文档 docs/superpowers/specs/2026-07-08-cicd-no-push-local-build-design.md
5.7 KiB
5.7 KiB
CI/CD 设计:本地构建部署(no-push)
日期:2026-07-08 状态:已批准,待实施 替代方案:2026-07-08 之前的 docker.yml + deploy.yml push 方案
1. 背景
1.1 现状问题
node-with-docker:22自定义镜像已丢失,原方案依赖它无法运行- 推送到 Gitea Registry 的拉取速度极慢,影响部署效率
- 用户习惯本地构建测试后再推送,无需保留历史构建产物
- 微服务架构下,拆分多个 workflow 文件(ci-ts/ci-go/docker/deploy)使流程碎片化
1.2 目标
- 不依赖任何自建镜像,全部使用官方镜像
- 不推送镜像到 registry,构建即部署
- 单文件管理整个 CI/CD 流程
- 支持回滚(不依赖 registry tag)
- 提供一次性预拉所有镜像的 compose 文件
2. 设计
2.1 架构总览
PR/push 触发
│
├─ quality-ts job (container: node:22-alpine) 并行
├─ quality-go job (container: golang:1.22-alpine) 并行
├─ quality-proto job (container: bufbuild/buf:latest) 并行
│
└─ deploy job (container: docker:25-git) 仅 push main, needs: [quality-*]
挂载 /var/run/docker.sock(DooD)
├─ docker compose up --build(本地构建 3 个服务)
└─ 健康检查轮询
2.2 文件结构
.github/workflows/
└─ ci.yml # 唯一的 CI/CD 文件
infra/
├─ docker-compose.deploy.yml # 改造:build: 替代 image:
├─ docker-compose.tools.yml # 新建:预拉所有 CI 需要的镜像
└─ deploy.env.example # 保留
2.3 ci.yml 设计
单文件多 job:
quality-ts:PR+push 都跑,container: node:22-alpine,pnpm install → lint → typecheck → test → buildquality-go:PR+push 都跑,container: golang:1.22-alpine,go mod download → vet → build → testquality-proto:PR+push 都跑,container: bufbuild/buf:latest,buf lint + buf breaking(仅 PR)deploy:仅 push main 或 workflow_dispatch 触发,needs: [quality-ts, quality-go, quality-proto]
deploy job 关键配置:
container: docker:25-git(官方镜像,自带 docker CLI + compose v2 + git)options: --volume /var/run/docker.sock:/var/run/docker.sock(DooD 模式)- 流程:checkout → cp compose 文件到 /opt/edu/ → docker compose up --build → 健康检查
回滚:
workflow_dispatch支持commit_sha输入- checkout 时使用指定 commit SHA
- 重新 build + deploy
2.4 docker-compose.deploy.yml 改造
所有服务从 image: 改为 build::
api-gateway:build: ./services/api-gatewayclasses:build: { context: ., dockerfile: services/classes/Dockerfile }(monorepo 上下文)teacher-portal:build: { context: ., dockerfile: apps/teacher-portal/Dockerfile }(monorepo 上下文)
删除 IMAGE_TAG 环境变量依赖。docker compose up --build 自动判断变更的服务。
2.5 docker-compose.tools.yml(预拉镜像)
用于一次性拉取所有 CI/构建需要的镜像到本地:
- CI 运行时:node:22-alpine、golang:1.22-alpine、bufbuild/buf:latest、docker:25-git
- 服务构建基础:node:20-alpine、golang:1.22-alpine、alpine:3.20
- 开发基础设施:mysql:8.0、redis:7-alpine
用法:docker compose -f infra/docker-compose.tools.yml pull
2.6 回滚策略
| 方式 | 操作 | 适用场景 |
|---|---|---|
| git revert | git revert <bad-commit> && git push → 自动触发 CI |
代码回滚(推荐) |
| 手动触发 | Actions → ci.yml → Run workflow → 填 commit_sha | 部署特定版本 |
2.7 actrunner 配置
container:
valid_volumes:
- /var/run/docker.sock
3. 实施步骤
- 删除现有 4 个 workflow 文件(ci-ts.yml、ci-go.yml、ci-proto.yml、docker.yml、deploy.yml)
- 创建
.github/workflows/ci.yml(合并单 workflow) - 改造
infra/docker-compose.deploy.yml(build 替代 image) - 创建
infra/docker-compose.tools.yml(预拉镜像) - 更新
.trae/rules/project_rules.md§15(no-push 模式规范) - 更新
docs/standards/cicd-runbook.md(删除 registry 章节,新增本地构建章节) - 提交并推送
4. 与旧方案对比
| 维度 | 旧方案(push 到 registry) | 新方案(no-push 本地构建) |
|---|---|---|
| workflow 文件数 | 4 个 | 1 个 |
| 镜像推送 | push 到 Gitea Registry | 不推送 |
| 部署方式 | compose pull + up | compose up --build |
| 自建镜像 | 依赖 node-with-docker:22 | 全用官方镜像 |
| 回滚 | 切换 registry tag | git revert / workflow_dispatch |
| 构建产物保留 | registry 保留历史 | 不保留 |
5. 风险与缓解
| 风险 | 缓解 |
|---|---|
| 本地镜像被清理后无法回滚 | 回滚走 git revert + 重新 build,不依赖镜像缓存 |
| docker.sock 挂载安全风险 | actrunner 仅在部署服务器运行,已隔离 |
| 构建慢 | layer cache 在宿主机本地,未变更的层秒过 |
| Gitea workflow_run 不支持 | 用 needs 串联,不用 workflow_run |