7bc74f06f2
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 6m47s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 42m10s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m59s
125 lines
6.2 KiB
Markdown
125 lines
6.2 KiB
Markdown
# AI 合同平台 V2 部署 Runbook
|
||
|
||
日期:2026-06-26
|
||
|
||
## 目标
|
||
|
||
把当前 V2 的本地启动、性能基线、安全收口、烟雾部署和生产变量收成一条可执行路径。
|
||
|
||
## 启动顺序
|
||
|
||
1. PostgreSQL 启动。
|
||
2. `postgres-init-databases` 创建 `yuqei_contract`、`yuqei_ai`、`yuqei_ops`。
|
||
3. `ai-platform-api-migrate` 执行 AI 库迁移。
|
||
4. `contract-api-migrate` 执行合同库迁移。
|
||
5. 启动 `ai-platform-api`、`contract-api`、worker、`contract-web`。
|
||
|
||
## 本地开发
|
||
|
||
根目录:
|
||
|
||
```powershell
|
||
Copy-Item yuqei-infra\compose\.env.example yuqei-infra\compose\.env
|
||
docker compose --env-file yuqei-infra\compose\.env -f yuqei-infra\compose\docker-compose.yml up --build
|
||
```
|
||
|
||
如果不走 Docker,服务单独启动命令已经在各自 `README.md` 中说明:
|
||
|
||
- `yuqei-contract-platform/services/contract-api/README.md`
|
||
- `yuqei-ai-platform/services/ai-platform-api/README.md`
|
||
- `yuqei-ai-platform/services/worker/README.md`
|
||
|
||
## 收口顺序
|
||
|
||
1. 先保留并复跑性能基线,确认高频路径仍在可交付区间。
|
||
2. 再跑安全扫描,把 bandit、npm audit、项目级 pip-audit 一起收口。
|
||
3. 最后整理部署文档和 smoke 命令,形成交付版本。
|
||
|
||
## 验证命令
|
||
|
||
```powershell
|
||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\verify-v2-runtime.ps1
|
||
```
|
||
|
||
```powershell
|
||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\verify-contract-review-worker-flow.ps1 `
|
||
-ContractApiBaseUrl http://localhost:8100 `
|
||
-WorkerExecutionMode docker-compose `
|
||
-RequireConfidence
|
||
```
|
||
|
||
## 烟雾部署
|
||
|
||
现有烟雾部署脚本:
|
||
|
||
```powershell
|
||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\deploy-v2-smoke-docker.ps1 `
|
||
-UseSshpass `
|
||
-AllowDirtyWorktree
|
||
```
|
||
|
||
最新一次已通过的 smoke 产物:
|
||
|
||
- `project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-07-16T11-12-47`
|
||
- Web: `http://192.168.3.90:13000`
|
||
- Contract API: `http://192.168.3.90:18100`
|
||
- AI Platform API: `http://192.168.3.90:18101`
|
||
- MinIO Console: `http://192.168.3.90:19001`
|
||
- AI golden sample asset gate:通过,`90` samples、`6/6` suites、`16/16` checks。
|
||
- Contract review worker smoke:通过。
|
||
- 远端数据库基线:`yuqei_contract`、`yuqei_ai`、`yuqei_ops` 均存在。
|
||
- 发布质量门:`project-docs/qa-artifacts/v2-release-quality-gate/2026-07-16T11-18-52`,带 `--run-benchmark` 复跑通过。
|
||
- 安全扫描:`project-docs/qa-artifacts/v2-security-scan/2026-07-12T13-08-00`,npm、Bandit、pip-audit 均为 0。
|
||
- 源码 secret 扫描:`project-docs/qa-artifacts/v2-source-secret-scan/2026-07-12T15-24-56`,覆盖冻结索引的 821 个文件;16 个候选均为已审计样例,新增未审计命中和陈旧基线均为 0。
|
||
- 接口压测:`project-docs/qa-artifacts/v2-interface-benchmark/2026-07-12T13-24-00`,7 个场景全部通过,错误率均为 0。
|
||
- Contract API:单 Uvicorn worker + 2 秒短读缓存;所有写请求前后清缓存。
|
||
- 无邮箱身份 smoke:公开注册/重置/邮箱验证关闭,管理员邀请与员工设密登录通过。
|
||
- 部署归档明确排除 `.env`、`.env.local`、`.env.production`、`.env.smoke`,本机 secret 不进入远端构建上下文。
|
||
|
||
## 生产基线
|
||
|
||
生产必须显式覆盖这些变量:
|
||
|
||
```text
|
||
CONTRACT_API_ENVIRONMENT=production
|
||
CONTRACT_API_DATABASE_AUTO_CREATE=false
|
||
CONTRACT_API_SEED_DEMO_DATA=false
|
||
CONTRACT_API_UVICORN_WORKERS=1
|
||
CONTRACT_API_READ_CACHE_TTL_SECONDS=2
|
||
CONTRACT_API_IDENTITY_EMAIL_DELIVERY_MODE=disabled
|
||
CONTRACT_API_IDENTITY_SELF_SERVICE_ENABLED=false
|
||
CONTRACT_API_IDENTITY_MANUAL_INVITATION_ENABLED=true
|
||
CONTRACT_API_IDENTITY_RATE_LIMIT_SECRET=LOAD_A_STABLE_RANDOM_SECRET_OF_AT_LEAST_32_CHARACTERS
|
||
AI_PLATFORM_ENVIRONMENT=production
|
||
AI_PLATFORM_DATABASE_AUTO_CREATE=false
|
||
AI_PLATFORM_UVICORN_WORKERS=1
|
||
YUQEI_WORKER_DATABASE_AUTO_CREATE=false
|
||
```
|
||
|
||
配套说明:
|
||
|
||
- 连接串从 `yuqei-infra/compose/.env.production.example` 开始替换。
|
||
- 生产不允许依赖自动建表。
|
||
- 发布前先迁移,再替换容器。
|
||
- 身份安全迁移的预期 Contract API head 为 `20260713_0031`;部署后必须验证 `identity_security_columns=ok`。
|
||
- 首次生产部署在迁移后、开放入口前运行一次 `python -m yuqei_contract_api.identity_bootstrap --tenant-id default --email <平台管理员邮箱> --password-file <只读 secret 文件>`。命令默认不覆盖已有凭据,轮换必须显式增加 `--force-rotate`。
|
||
- 当前首发采用管理员线下开通:关闭公开注册、密码重置和邮箱验证;管理员在后台生成一次性邀请链接并通过可信渠道交付。
|
||
- 以后启用 SMTP 时,必须将 `IDENTITY_MANUAL_INVITATION_ENABLED` 改为 `false`,SMTP 凭据只能来自受保护环境或只读 secret 文件。
|
||
- 互联网反向代理必须覆盖客户端传入的 `X-Real-IP` / `X-Forwarded-For`,避免伪造 IP 绕过验证码限流。
|
||
- 当前短读缓存是进程内缓存;当 `CONTRACT_API_UVICORN_WORKERS>1` 时会自动禁用。生产扩容到多 worker 前,应先接入支持跨进程失效的共享缓存。
|
||
|
||
## 回滚策略
|
||
|
||
- 保留上一次 smoke 成功的归档和镜像信息。
|
||
- 如果健康检查、数据库基线或 worker smoke 失败,停止继续推进生产替换。
|
||
- 先修复迁移/配置,再重新跑 smoke。
|
||
|
||
## 已知限制
|
||
|
||
- 本机是否具备 Docker 不再作为发布前置;权威 smoke 以 `192.168.3.90` 远端 Docker 环境为准。
|
||
- Trace governance 的 24 小时 smoke 观察窗口列为上线前检查项,production 暂不开启,不阻塞当前交付收口。
|
||
- 代码与依赖审计已经可以在本机或 CI 独立完成,不依赖 Docker。
|
||
- 源码 secret 门禁使用 `detect-secrets==1.5.0` 和已审计基线;新增未审计命中会阻断 CI,扫描 artifact 写入 `project-docs/qa-artifacts/v2-source-secret-scan`。
|
||
- 身份线下开通、SMTP 与验证码安全的配置、验证和回滚说明见 `project-docs/V2-production-identity-email-security-2026-07-13.md`。
|
||
- backend-only production compose、HTTPS edge、只读 preflight、异地备份/恢复验证和真实 Provider 18 样本验收见 `project-docs/V2-production-infrastructure-provider-acceptance-2026-07-16.md` 与 `yuqei-infra/deploy/README.md`。这些入口默认不切换流量。
|