29 KiB
Edu 项目规则(微服务版)
版本:1.0 日期:2026-07-08 适用范围:Edu 微服务架构(DDD + EDA + CQRS,多语言 monorepo) 关联文档:
1. 架构图优先规则
任何任务开始前,必须先查阅架构影响地图,通过图定位代码和模块。
- 先图后码:执行任何分析、修改、搜索任务时,首先运行
pnpm run arch:scan更新 arch.db,再通过pnpm run arch:query查询目标模块、函数、依赖关系,结合阅读docs/architecture/004_architecture_impact_map.md定位架构设计意图,最后按图索骥读取源码 - 图未覆盖则先补图:如果发现项目中存在 arch.db 未记录的模块、函数、表、路由、proto 等结构,必须先运行
pnpm run arch:scan重新扫描(多语言扫描器:TS + Go + Python + Proto),然后检查 004 是否需要补充 - 改码必同步图:对源码的任何修改完成后,必须运行
pnpm run arch:scan更新 arch.db;若架构设计意图有变化,同步更新 004
架构文档清单
| 文档 | 用途 |
|---|---|
docs/architecture/004_architecture_impact_map.md |
架构设计意图唯一源(人类可读) |
docs/architecture/0010_architecture.md |
理想蓝图(目标态) |
docs/architecture/roadmap/ |
长远规划(tech-debt / pending-features) |
docs/architecture/runbooks/ |
运维手册(P6 硬化、post-p6-followup、incident-response) |
docs/troubleshooting/known-issues.md |
已知问题速查(场景→技术映射,索引式,不写工作日志) |
需要同步图的场景
- 新增/删除/重命名导出函数、组件、Hook、类型
- 修改函数签名(参数、返回类型)
- 修改权限点(Permissions 常量)或角色-权限映射
- 新增/删除数据库表
- 新增/删除路由页面、API 路由、gRPC 服务、proto message
- 修改模块间依赖关系或服务间调用关系
- 新增服务、新增模块、新增 proto 定义
- 修改 Kafka topic、Outbox 事件命名
同步方式
- 修改源码后运行
pnpm run arch:scan更新 arch.db(强制) - 若架构设计意图变化,同步更新
docs/architecture/004_architecture_impact_map.md - 若发现新的"场景→技术"映射或工作经验,更新
docs/troubleshooting/known-issues.md
2. 架构元数据库规则(arch.db)
arch.db 是代码结构唯一源,AI 工作前必须运行 pnpm run arch:scan 更新。
- 多语言扫描:arch.db 覆盖 TypeScript(ts-morph)、Go(tree-sitter-go)、Python(tree-sitter-python)、Proto(buf AST)四类语言
- 查询命令:
pnpm run arch:query -- sql "<SQL>"自定义 SQL 查询pnpm run arch:query -- module-deps查模块依赖pnpm run arch:query -- module-reverse-deps <module>查反向依赖pnpm run arch:query -- symbol-refs <symbol>查符号引用链pnpm run arch:query -- tech-usage <tag>查技术使用pnpm run arch:query -- violations查架构违规pnpm run arch:query -- stats查总体统计pnpm run arch:query -- modules查模块列表
- arch.db 不替代 004:arch.db 是"代码现状",004 是"设计意图",两者互补
- 预期规模:模块数 ≥ 10(api-gateway、push-gateway、teacher-bff、iam、classes、core-edu、content、msg、data-ana、ai),符号数 ≥ 100
3. 编码规范
详细规范见 docs/standards/coding-standards.md,以下为核心强制规则。
3.1 代码质量规则
- 每次修改后运行
pnpm run lint和pnpm run typecheck确保零错误 - TypeScript 服务必须用
@RequirePermission()装饰器进行权限校验 - 前端组件禁止使用
role === "xxx"硬编码,统一使用usePermission().hasPermission() - 单文件行数遵循企业级规范:
- 配置文件、常量文件、类型定义文件、proto:无限制
- Controller / Service:建议 ≤ 500 行
- Repository / data-access:建议 ≤ 800 行
- 工具函数:建议 ≤ 40 行
- 自定义 Hook:建议 ≤ 80 行
- 硬性上限:任何文件不超过 1000 行,超过必须拆分
3.2 架构分层规则(微服务)
- 四层分层:Gateway → BFF → Services → Data
- 依赖方向单向:Gateway → BFF → Services → Data,禁止反向依赖
- 服务间通信:通过 protobuf gRPC 或 Kafka 事件,禁止直接访问对方 DB
- Gateway 职责:JWT 校验、限流、熔断、CORS、请求 ID 注入
- BFF 职责:聚合多个 Service 的数据,为前端提供场景化 API
- Service 职责:业务逻辑,每服务独占 DB(DDD 限界上下文)
3.3 模块标准结构(DDD)
services/[service]/src/
├─ [domain]/ # 限界上下文
│ ├─ *.controller.ts # Controller(HTTP/gRPC 入口)
│ ├─ *.service.ts # Application Service(编排层)
│ ├─ *.repository.ts # Repository(数据访问)
│ ├─ *.schema.ts # Zod 验证
│ └─ *.dto.ts # DTO
├─ config/ # 配置(database / env / kafka / neo4j / elasticsearch)
├─ middleware/ # 中间件(auth.middleware / permission.guard)
├─ shared/ # 共享
│ ├─ errors/ # 错误(application-error / global-error.filter)
│ ├─ health/ # 健康检查
│ ├─ lifecycle/ # 生命周期
│ ├─ observability/ # 可观测性(logger / metrics / tracer)
│ └─ outbox/ # Outbox(仅事件驱动服务)
├─ app.module.ts # 根模块
└─ main.ts # 入口
3.4 TypeScript 规则
- 禁止
any:未知类型用unknown并做类型守卫 - 禁止
as断言(除非从unknown转换或测试中,需注释原因) - 函数返回值必须显式标注,特别是
Promise<T> - 仅用于类型的导入必须使用
import type - 可选链后禁止跟非空断言
! - ESM 模式:NestJS ESM 模式下,相对 import 的
.js后缀(构建产物)
3.5 Go 规则
- 包名小写单词,不使用下划线或驼峰
- 导出函数必须有 doc comment(
// FuncName ...) - 错误处理:
if err != nil { return err },禁止_ = err - 不使用
interface{},用any(Go 1.18+) - 包内文件命名 lowercase,不使用下划线(除
_test.go) - 中间件位于
internal/middleware/,路由位于internal/routing/
3.6 Python 规则
- 类型注解强制(所有函数签名、变量声明)
- FastAPI 路由用
APIRouter - 异步优先:
async def,IO 密集场景禁止同步阻塞调用 - 模块名 snake_case,类名 PascalCase
- 配置统一通过
pydantic-settings管理(config.py)
3.7 命名规范(多语言)
| 对象 | 规范 | 示例 |
|---|---|---|
| 目录 | kebab-case | api-gateway/、core-edu/ |
| TS 组件 | PascalCase | UserController.ts |
| TS Hook | camelCase | useAuth.ts |
| Go 文件 | lowercase | circuitbreaker.go |
| Python 文件 | snake_case | clickhouse_client.py |
| Proto 文件 | snake_case | core_edu.proto |
| 变量/函数 | camelCase(TS)/ lowercase(Go)/ snake_case(Py) | getUserById / getUserById / get_user_by_id |
| 常量 | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
| 类/接口 | PascalCase,接口不加 I 前缀 |
UserService |
| 布尔值 | is/has/can/should 前缀 |
isActive、hasPermission |
3.8 Controller / Server Action 规范
- 每个 Controller 方法必须用
@RequirePermission()装饰器声明权限 - 输入用 Zod / class-validator 验证,验证失败返回结构化错误
- 返回 protobuf message 或 DTO(结构同 ActionState)
- 错误统一走
GlobalErrorFilter - BFF Controller 聚合多个 Service 调用,禁止直接访问 DB
3.9 Tailwind 规范
- 使用
cn()工具函数管理条件类名 - 禁止字符串拼接动态类名(
bg-${color}-500) - 禁止使用任意值(
w-[137px]),除非有充分理由并注释 - 设计令牌在
packages/shared-tokens/(待建立)或apps/teacher-portal/src/app/styles/tokens/
3.10 设计令牌规范(强制)
- 禁止硬编码颜色:TSX/TS/CSS 中不得出现
#hex颜色字面量,统一使用hsl(var(--*))或 Tailwind 类bg-* - 禁止硬编码字体:不得出现
'Inter'/'Fraunces'/'JetBrains Mono'字面量,使用var(--font-family-sans/serif/mono) - 禁止硬编码字号:不得出现
font-size: Npx,使用var(--font-size-1~9) - 禁止 Tailwind 任意值:不得使用
w-[Npx]/h-[Npx]/p-[Npx]等,映射到--space-*或 Tailwind 默认阶梯 - 三层令牌:
- Layer 1 Primitive:原始色板/字号/间距/阴影,业务代码不直接引用
- Layer 2 Semantic:语义令牌(light/dark),业务代码唯一引用入口
- Layer 3 Tailwind Theme:
@theme inline将 Semantic 令牌暴露为bg-*/text-*/font-*类
- 改令牌必同步图:修改令牌定义后,同步更新 004 与 arch.db
- ESLint 强制约束:
no-restricted-syntax:禁止#hex字面量design-tokens/no-hardcoded-fonts:禁止'Inter'/'Fraunces'字面量- 白名单:
primitive.css、email-channel、manifest.ts
4. 安全规范
- JWT RS256:IAM 签发,Gateway 公钥校验(不共享密钥)
- Cookie:
httpOnly + Secure + SameSite=Strict - 环境变量:服务端变量不加
NEXT_PUBLIC_前缀;前端变量必须加 - 环境校验:用
@t3-oss/env-nextjs+ Zod 或pydantic-settings校验 - 禁止
dangerouslySetInnerHTML(如必须使用,先用 DOMPurify 清洗) - 密码哈希:bcrypt(cost ≥ 12),禁止 MD5/SHA1
- 限流:Gateway 层 IP 级令牌桶,登录接口额外加用户级限流
- CORS:白名单域名,禁止
* - WAF:见
infra/security/waf-rules.conf
5. 契约规范
- 契约先行:服务间通信先定
.proto,再写实现 - 工具链:protobuf + buf v2
- buf lint:
STANDARD规则集 - buf breaking:
FILE级别检查(CI 强制) - proto 文件位置:
packages/shared-proto/proto/ - 包名规范:
edu.<domain>.v1(如edu.iam.v1、edu.core_edu.v1) - 生成代码:
buf generate(TS 走buf.gen.yaml,Go/Python 各自配置) - gRPC 服务端口:每服务独立端口,见 004 服务清单
6. 事件驱动规范
- Outbox 模式:事务内写业务表 + outbox 表,独立 publisher 投递到 Kafka(保证 at-least-once)
- 事件命名:
<Aggregate>.<Action>(如ExamCreated、HomeworkSubmitted、GradeReleased) - TOPIC_MAP 路由:每个服务维护
事件 → topic映射(见shared/outbox/) - 幂等性:
- Kafka producer:
idempotent=true+transactionalId - Consumer:基于
event_id去重(Redis SETNX 或 DB 唯一索引)
- Kafka producer:
- CDC:MySQL → Debezium → Kafka(可选,用于读模型同步)
- 事件版本:schema 演化用
v1/v2后缀,禁止破坏性变更
7. 提交规范
- 使用 Conventional Commits 格式:
feat(scope): description - 类型:
feat、fix、chore、docs、style、refactor、test、perf、ci - scope(服务名或包名):
- 服务:
iam、classes、core-edu、content、msg、ai、data-ana、api-gateway、push-gateway、teacher-bff - 包:
shared-proto、shared-ts、shared-go、shared-py、shared-tokens - 基础设施:
infra、k8s、helm、ci - 文档:
docs
- 服务:
- 提交前必须运行:
pnpm run lint+pnpm run typecheck(TS);go vet ./...(Go);ruff check src/(Python) - commitlint + husky:强制校验(见
.commitlintrc.js、.husky/commit-msg)
8. Git 工作流
- 分支策略:分支开发。人类决策者手动维护分支(创建分支、合并到 main),AI 不得自行切换/创建/合并分支
- AI 分支约束(强制):
- AI 只在人类分配的当前分支上工作
- 禁止
git checkout -b、git switch、git branch创建或切换分支 - 禁止
git merge、git push origin main(合并与推送 main 由人类负责) - AI 完成工作后
git add+git commit提交到当前分支,通知人类合并
- 提交前校验:commit 前必须本地通过
pnpm run lint+pnpm run typecheck(TS)/go vet ./...(Go)/ruff check src/(Python) - pre-commit hook:
lint-staged自动修复 + 校验(见lint-staged.config.js) - commit-msg hook:commitlint 校验格式
- 回滚:由人类在 main 上
git revert <commit>,不使用分支回滚 - 默认多 AI 协作:所有工作默认按多 AI 合作模式进行(见 §14),每个 AI 在各自分支独立工作
9. 问题记录规则
所有工作完成后,必须将遇到的问题记录到 docs/troubleshooting/known-issues.md(索引式速查手册)。
必须记录的场景
| 场景 | 记录要求 |
|---|---|
| 构建报错(dev/build/lint/tsc/go vet/ruff) | 记录到"全局经验"对应主题分区 |
| 运行时异常(白屏/API 报错/数据加载失败/gRPC 错误) | 记录到"模块经验"对应模块分区 |
| 框架/库版本兼容问题 | 记录到"全局经验: 框架与运行时" |
| 依赖配置问题(go mod / uv / pnpm workspace) | 记录到"全局经验: 依赖管理" |
| 架构约束违规(跨服务访问 DB / 缺契约) | 记录到"全局经验: 架构约束" |
| 多语言 monorepo 问题(共享包链接失败等) | 记录到"全局经验: 多语言 monorepo" |
记录格式
索引式表格,指明"场景→技术/规则"映射,不写多行代码示例:
### X.X 主题分区
| 场景 | 技术/规则 |
| -------- | ------------------ |
| 简述场景 | 正确做法(一句话) |
记录要求
- 索引式:场景→技术/规则映射,不写代码示例和错误示范列
- 去重:同类问题在原条目补充,不重复创建
- 引用架构规则:架构分层、模块结构等规则引用 004 和本规则文件,不重复
- 只读自己模块分区:AI 查阅 known-issues 时只读自己负责模块的分区,禁止读其他 AI 模块的分区(避免被历史记录误导)
- 禁止工作日志:known-issues 不设"工作经验日志"区,不写流水账、不写"做了什么/学到什么"
- 经验沉淀不标注 AI 身份:所有经验记录只写"场景→技术/规则"映射,不得出现 AI 标识(如 ai01/ai02/coord 等),避免新同名 AI 将前任记录误认为当前事实
- 模块内经验:模块内的经验沉淀在各自模块的 README/文档中,同样不标注 AI 身份
10. AI 工作强制流程
所有 AI 工作必须遵循此流程,违反即违规。
阶段 1:上下文加载(按需阅读,严格模块边界)
架构文档按需阅读:模块开发只读自己模块的架构与服务 README;项目整体相关工作(跨模块契约、基础设施、文档体系、shared-proto)才读全局架构文档。功能开发/文档书写等强依赖场景必须读对应架构。
严格模块边界:AI 只读自己负责模块的文档与源码,不越界阅读其他模块的内部实现细节(避免被历史记录或他人方案误导)。仅在需要确认跨模块契约时,才读对方的对外接口(proto/API/事件)。
pnpm run arch:scan更新 arch.dbpnpm run arch:query -- module-deps查目标模块依赖pnpm run arch:query -- symbol-refs <目标函数>查调用链- 阅读
services/[service]/README.md读自己模块的工作流程 - 查
docs/troubleshooting/known-issues.md仅读自己模块的分区,禁止读其他 AI 模块分区 - 模块开发:查
docs/architecture/004_architecture_impact_map.md对应模块章节;全局工作:查 004 全文
阶段 2:执行工作
- 按规划执行(契约先行:先 proto,再实现)
- 修改代码后立即运行
pnpm run arch:scan更新 arch.db - 运行质量校验确保零错误:
- TS:
pnpm run lint+pnpm run typecheck - Go:
go vet ./...+go build ./... - Python:
ruff check src/
- TS:
阶段 3:经验沉淀(强制,不可跳过)
- 若发现新的"场景→技术"映射 → 提炼到
docs/troubleshooting/known-issues.md对应模块分区(索引式一行,不写流水日志,不标注 AI 身份) - 若发现新的架构决策 → 更新 004
- 若代码结构变化 →
pnpm run arch:scan确认 arch.db 已更新 - 模块内的经验沉淀到自己模块的 README/文档,不污染全局 known-issues,同样不标注 AI 身份
禁止在 known-issues.md 写"工作经验日志/流水账"。known-issues 是索引式速查手册,只保留场景→技术映射,不出现任何 AI 标识。
11. 多语言 monorepo 规则
- 包管理器分工:
- TypeScript:pnpm workspace(
pnpm-workspace.yaml) - Go:go.work(
go.work) - Python:uv workspace(根
pyproject.toml的[tool.uv.workspace])
- TypeScript:pnpm workspace(
- 共享包(
packages/):shared-proto:protobuf 契约定义(跨语言共享)shared-ts:TypeScript 共享类型与工具(待建立)shared-go:Go 共享工具(待建立)shared-py:Python 共享工具(待建立)shared-tokens:设计令牌(待建立)
- 跨语言契约:通过 protobuf,禁止 JSON Schema 或 OpenAPI 作为内部契约
- 依赖版本对齐:共享依赖(如 uuid、jwt)在多语言版本号保持一致
12. 可观测性规范
- 三支柱必须同时启用(所有服务):
- 日志:pino(TS)/ zap(Go)/ structlog(Python)—— 结构化 JSON
- 指标:prom-client(TS)/ prometheus(Go)/ prometheus-client(Python)——
/metrics端点 - 链路:OpenTelemetry SDK + OTLP exporter —— 统一 traceparent
- 健康检查:
/health(liveness)+/ready(readiness),见各服务shared/health/ - 请求 ID:Gateway 注入
X-Request-Id,全链路传递(日志、metrics、trace) - 指标命名:
<service>_<module>_<operation>_<unit>(如iam_login_duration_seconds) - 告警规则:见
infra/prometheus/rules.yml+infra/alertmanager/alertmanager.yml - Grafana 面板:见
infra/grafana/dashboards/
13. 部署与基础设施规范
- 容器化:每服务独立 Dockerfile(见
services/[service]/Dockerfile) - K8s:基础设施 manifest 位于
infra/k8s/,演化目标为 Helm chart(见infra/k8s/helm/) - 命名空间:
edu-system、edu-monitoring、edu-chaos、edu-backup - 配置分离:
- ConfigMap:非敏感配置(环境变量、特性开关)
- Secret:敏感配置(DB 密码、JWT 密钥、API key)—— 见
infra/security/secrets.example.env
- 备份:见
infra/backup/backup-mysql.sh,每服务独立备份,保留 7 天 - 监控栈:Prometheus + Grafana + Alertmanager(见
infra/docker-compose.monitoring.yml) - 混沌工程:见
infra/chaos/experiments.yaml
14. 多 AI 协作规范
默认多 AI 协作:所有 AI 工作默认按多 AI 合作模式进行。详细流程见 多 AI 协作指南,本节为强制约束摘要。
14.1 角色与权限
| 角色 | 职责 | 在分支提交 | 合并到 main | force push main |
|---|---|---|---|---|
| 协调 AI(Coordinator) | 契约管理、交叉审查、冲突仲裁、发布 | ✅ | ❌(由人类合并) | ⚠️(仅事故) |
| 开发 AI(Dev) | 按模块分工写代码、在分支提交 | ✅ | ❌ | ❌ |
| SRE AI | infra/ 维护、部署 |
✅(infra) | ❌(由人类合并) | ⚠️(仅事故) |
| 人类决策者 | 架构决策、分支管理、合并、Breaking Change 审批、发布确认 | — | ✅(手动合并分支到 main) | ⚠️(仅事故) |
AI 在分配的分支上提交,不自行合并到 main。合并由人类决策者负责。
14.2 模块单一负责制与模块边界(强制)
- 每个模块(限界上下文)只有一个 AI 负责,禁止并行修改同一模块
- 严格模块边界:AI 只修改自己负责的目录(
services/<my-service>/或apps/<my-app>/),禁止越界修改他人模块的源码 - 只读自己模块文档:AI 阅读文档时只读自己模块的 README/设计文档/known-issues 分区,禁止阅读其他 AI 模块的内部文档和历史记录(避免被前任同名 AI 的过时方案/审计结果误导)
- 跨模块契约只读接口:需要确认跨模块协同时,只读对方的对外接口(proto message / API 端点 / Kafka 事件 schema),不读对方内部实现
shared-proto、shared-tokens、docs/由协调 AI 维护,开发 AI 只读引用infra/由 SRE AI 专门负责,业务 AI 不直接修改
14.3 分支开发规则(强制)
- 分支由人类创建:人类决策者为每个任务/模块创建分支并分配给 AI,AI 不得自行创建分支
- AI 禁止切换分支:AI 不得执行
git checkout -b、git switch、git branch等分支创建/切换命令 - AI 禁止合并/推送 main:
git merge、git push origin main由人类决策者执行,AI 只提交到当前分支 - AI 提交流程:
git add <files>→git commit -m "<type>(<scope>): <subject>"→ 通知人类合并 - 提交前校验:commit 前必须本地通过
pnpm run lint+pnpm run typecheck(TS)/go vet ./...(Go)/ruff check src/(Python) - 提交信息规范:遵循 Conventional Commits(见 §7)
14.4 跨模块变更顺序(强制)
修改涉及多模块时,按依赖顺序依次在各模块分支完成,由人类决策者按顺序合并到 main:
shared-proto(proto 契约)- 业务服务(classes / iam / core-edu 等)
api-gateway(路由)- BFF(teacher-bff 等)
- 微前端(teacher-portal 等)
每合并一层到 main 后,再合并下一层。协调 AI 负责监督顺序,避免越级合并导致下游构建失败。
14.5 冲突处理规则
- 分支冲突:由人类决策者在合并时解决,或通知 AI 在分支上
git rebase最新 main 后重新提交 - 架构冲突:由协调 AI 仲裁保留方案,通过新 commit 修正
- 禁止
git push --force到 main:仅协调 AI 在事故时可--force-with-lease
14.6 经验沉淀规则(强制)
- 不记录工作日志:AI 不在 known-issues.md 或任何文档中写"工作经验日志/流水账"
- 只做经验沉淀:遇到新的"场景→技术"映射,以索引式一行记录到 known-issues 对应模块分区
- 不标注 AI 身份:经验沉淀记录不得出现 AI 标识(如 ai01/ai02/coord 等),避免新同名 AI 误读
- 模块内经验:模块内的经验沉淀到各自服务 README/文档,同样不标注 AI 身份
14.7 敏感文件保护
以下文件修改需人类决策者额外审批:
.env、.env.example、infra/security/secrets.example.envinfra/k8s/(生产部署).github/workflows/(CI 配置).trae/rules/project_rules.md(项目规则)
15. CI/CD 规范
详细配置见
.github/workflows/ci.yml,使用手册见 cicd-runbook,设计文档见 no-push-local-build-design。
15.1 核心模式:no-push 本地构建
- 不推送镜像到 registry:构建即部署,镜像只存在于构建机本地
- 不依赖自建镜像:全部使用官方镜像(node:22-alpine / golang:1.22-alpine / bufbuild/buf / docker:25-git)
- DooD 模式:deploy job 容器挂载
/var/run/docker.sock,容器内 docker 命令作用于宿主机 - 单文件管理:一个
.github/workflows/ci.yml管全部 CI/CD
15.2 流水线阶段
| 阶段 | 并行 | 内容 | 失败策略 |
|---|---|---|---|
| quality-ts | ✅ | pnpm lint + typecheck + test + build | 失败阻断 |
| quality-go | ✅ | go vet + build + test | 失败阻断 |
| quality-proto | ✅ | buf lint + buf breaking | 失败阻断 |
| deploy | 串行 | docker compose up --build + 健康检查 | 失败阻断 |
质量检查在分支推送时触发,部署仅在合并到 main 时触发。
15.3 触发条件
| 事件 | 触发阶段 | 触发条件 |
|---|---|---|
| 分支 push / PR | quality-ts + quality-go + quality-proto(并行) | 分支推送自动 |
| push 到 main | 上述全部 + deploy | 合并后自动 |
| workflow_dispatch | 上述全部 + deploy | 手动触发,支持 commit_sha 回滚 |
不再支持 tag 发布:no-push 模式下不用
git tag v*触发。版本管理通过 commit SHA 追溯。
15.4 镜像规范
- 不推送到 registry,本地构建本地使用
- 不保留历史镜像:layer cache 在宿主机本地,未变更的层秒过
- 回滚:
git revert重跑 CI,或workflow_dispatch指定commit_sha
15.5 部署策略
- 目标环境:服务器 Docker Compose(P1-P2 阶段),K8s(P3+ 阶段)
- 部署方式:
docker compose up -d --build --remove-orphans(在/opt/edu/目录) - 部署目录:
/opt/edu/(compose 文件)+/opt/edu/repo/(CI 同步的源码,供 build.context 使用) - 健康检查:部署后轮询
/healthz端点(10 次 × 6 秒),失败输出容器日志 - 回滚:
git revert + push或workflow_dispatch指定commit_sha
15.6 必需的 CI 文件
| 文件 | 用途 |
|---|---|
.github/workflows/ci.yml |
唯一 CI/CD 流水线(quality + deploy) |
infra/docker-compose.deploy.yml |
部署用 compose(build: 替代 image:) |
infra/docker-compose.tools.yml |
一次性预拉所有 CI 镜像 |
infra/deploy.env.example |
部署环境变量模板 |
15.7 actrunner 配置
# /etc/gitea/act_runner/config.yaml
container:
valid_volumes:
- /var/run/docker.sock
15.8 镜像预拉(一次性)
部署前在服务器执行:
docker compose -f infra/docker-compose.tools.yml pull
拉取清单:node:22-alpine、golang:1.22-alpine、bufbuild/buf:latest、docker:25-git、node:20-alpine、alpine:3.20、mysql:8.0(开发测试)、redis:7-alpine(开发测试)。
本规则文件是项目的强制约束,所有 contributor(含 AI)必须遵守。规则变更需同步更新 004 与 arch.db。