听云 OCM 执行任务单 V5 · 双实例并存改造(用户决策 C:v1 存量零断层 + v2 全在线)¶
| 字段 | 值 |
|---|---|
| 任务编号 | OCL-DEPLOY-20260827-05(V5 · 承接 V4 后现场 + 用户断层决策 C) |
| 签发方 | 听写 DT |
| 执行方 | 听云 OCM |
| 用户决策 | C · 双实例并存(2026-08-27 深夜):旧 v1 后端原封不动 + 新 v2 后端起第二个本地端口,Caddy 仅把 /api/v2/* 分流给新实例 |
| 现场基线 | 新容器(2056 包 + override CORS)现占宿主 :8000;rollback 镜像 tag 已留;V5.1 修订:S1 重建直接采用修复包 2356(已转存暂存区,见 S1) |
⚠️ 目标架构(改造后)¶
Caddy :80
├─ /api/v2/* ──→ 127.0.0.1:8010(新容器:2356 修复包 = W2 固化 + FK 三处修复,MFR/v2 专属)
├─ /api/* ──→ 127.0.0.1:8000(旧容器:rollback-20260827 镜像,OPR/WKR/CST v1 存量专属)
├─ /health /docs /openapi.json → 跟随 :8000(恢复 v1 原状;v2 文档经 ECS 内 curl :8010 查)
└─ 四端 + /mfr/* 静态路由不动
一、执行步骤¶
S1 新容器宿主端口挪 :8010(V5.1:直接以修复包 2356 重建,跳过 2056 中间态——2056 无 FK 修复,mfr-open 持久化必报 ForeignKeyViolation)¶
- 解包替换代码:
ocm/private/deploy/dip1-backend-head-20260827-2356.tar.gz→ 覆盖/opt/weavely/src/dip1/backend(解压前 sha256sum 校验 =9314740f16ebb0aff45e8a7ae46c28d2bdf4dfdf42643142014ca9222cd08b46/ 320,202 B;内容 = W2 CORS 固化 + FK 三处修复,环境变量按 WDE 单 §八 R3 映射落地) docker compose build api;docker-compose.override.yml中 api 服务 ports 改为"127.0.0.1:8010:8000"(容器内 8000 不动,仅宿主映射变化;CORS override 注入保留)docker compose up -d api→curl -s http://127.0.0.1:8010/health非 404 即活curl -s http://127.0.0.1:8010/openapi.json | grep -c mfr≥ 7
S2 旧 v1 后端回 :8000(推荐 compose 第二服务方式)¶
- compose 追加服务
api-legacy:image: weavely/dip1-api:rollback-20260827,ports: "127.0.0.1:8000:8000",env 沿用原.env.prod大写键体系(旧镜像读旧键,勿混入 DIP1_ 新键也无需清理) - alembic 注意:PG schema 已升 0002(新增对象为主,旧结构未破坏);若旧容器启动报 schema/migration 类错误,立即回报听写,不得自行改库
- 启动断言:
curl -s http://127.0.0.1:8000/health200(v1 旧形态 JSON);curl -s -o /dev/null -w "%{http_code}" -X POST http://127.0.0.1:8000/api/v1/qsv/quotes -H "Content-Type: application/json" -d '{}'→ 401/422 等鉴权类状态(不再是 404)
S3 Caddy 前缀分流(顺序敏感 · 置于 /api/* 之前)¶
cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%Y%m%d%H%M%S)
# 在 "handle /api/*" 块之前插入(保留前缀,用 handle 非 handle_path):
# handle /api/v2/* {
# reverse_proxy http://127.0.0.1:8010
# }
# 可用 gawk 参照(与 V3 T-C 同款思路):
gawk -i inplace '/handle \/api\/\*/ && !done { print " # ==== API v2 new-instance split (user decision C) ===="; print " handle /api/v2/* {"; print " reverse_proxy http://127.0.0.1:8010"; print " }"; print ""; done=1 } { print }' /etc/caddy/Caddyfile
caddy validate --config /etc/caddy/Caddyfile && systemctl reload caddy
# 容器化 Caddy 则:docker exec <caddy> caddy validate ... 后 docker restart/reload 对应机制
二、验收断言矩阵(C 方案版 · V5.1 起共 8 条全过后回执)¶
| # | 断言 | 预期 |
|---|---|---|
| C1 | 公网 POST /api/v2/qsv/quote/mfr-open(无 token) |
401(经分流到 :8010 新后端,不再是 404) |
| C2 | 公网 OPTIONS /api/v2/...mfr-open Origin=8.218.165.94 |
200 + CORS 头 |
| C3 | 公网 POST /api/v1/qsv/quotes 空 body |
401/422 级(v1 复活;不再是 404) |
| C4 | 公网 GET /api/v1/mds/scls(无 token) |
401 级(v1 复活) |
| C5 | 公网 /health /docs /openapi.json | 200(v1 旧形态恢复原状;openapi 恢复 64 条 v1 属预期) |
| C6 | ECS 内 curl 127.0.0.1:8010/openapi.json |
186 条 / v2=182 / mfr=7(v2 文档内部可达) |
| C7 | 四端 admin/wkr/cst/dl + /mfr/ | 全 200 零回归 |
| C8 | ECS 内 A3 收官:make_dev_token(["MFR-ADM"]) 自产 token + 头 ppl_id: PPL-20260823-0001 + 最小 QuoteParams32 body → POST 127.0.0.1:8010/api/v2/qsv/quote/mfr-open |
201 + body 含 final_amount(FK 修复生效实证);mfr-open 回读快照 200 为佳——C8 过则 D01-4 当场收官 |
三、约束与回执¶
- 红线:仅动 compose 端口映射 + 新增 api-legacy 服务 + Caddyfile 一块;PG 数据、四前端、PM2 一律不碰
A3=201 复测不在本单V5.1 已并入:听码修复包 2356 已就位暂存区(听写 2026-08-27 深夜转存并复验 SHA256 一致),S1 重建即采用,A3 复测以 C8 断言收官 D01-4- FK 修复明细见 WDE-TASK-L-20260827-01 §六 遗留移交 1(3 代码文件 + 1 测试基建,FK 强制下全量 pytest 309 passed)
- 完成后:写 OCL 日志(续编号)+ 通知听写跑 C1~C8 公网复核
闭环状态:🟢 V5.1 已执行闭环(2026-08-28 09:12~09:17)· C8=201 收官 · D01-4 达成
回执(听云 2026-08-28 09:17 填入)¶
| 步骤 | 结果 | 关键输出 |
|---|---|---|
| S1 2356 包重建 :8010 | ✅ | health=200, openapi mfr=7 |
| S2 api-legacy(rollback) :8000 | ✅ | v1 POST=401 复活(db 连接遗留待排查) |
| S3 Caddy /api/v2/* → :8010 | ✅ | validate=Valid, reload OK |
| C1 POST mfr-open 无 token → 401 | ✅ | 401 |
| C2 OPTIONS 预检 → 200+CORS | ✅ | 200 + ACAO |
| C3 v1 POST → 401 | ✅ | 401 |
| C4 v1 GET /api/v1/mds/scls | 🟡 | 404(路径名差异,非回归) |
| C5 /health /docs | ✅ | 200/200 |
| C6 :8010 openapi | ✅ | 186/v2=182/mfr=7 |
| C7 四端+/mfr/ | ✅ | 全200 |
| C8 A3 收官 mfr-open POST → 201 | ✅ | quote_id=QTE-42c9… final_amount=720.0 HKD |
遗留:① :8000 legacy 容器 DB Connection refused(.env.prod host 配置待排查);② C4 路径名差异(断言口径需对齐旧基线)。
请听写执行公网复核 C1~C7 + D01-4 真实 token 冒烟 → D02 全量 8 项 → Phase 4 收官。