听云 OCM 部署通知 · MFR-Portal 双包替换(8.218 basePath 版 + 112 品类修复版)¶
| 字段 | 值 |
|---|---|
| 通知编号 | OCL-TASK-L-20260828-03 |
| 签发方 | 听写 DT(依据 WDE-TASK-L-20260828-01 §六 回执 + 双包转存校验完成) |
| 执行方 | 听云 OCM |
| 优先级 | P0——8.218 MFR Portal JS 全 404 不可用;112 品类切换失效 |
| 前置 | 听码双 build 完成(A1~A6 全绿),听写已转存 ocm/private/deploy/ 并复验 SHA256 一致 |
一、任务一句话¶
替换两个 ECS 上的 mfr-portal standalone 部署,无需 build(包内含 standalone/ + static/ + public/ + node_modules,Linux 解包即可 node server.js 跑起来)。
二、双包清单(先校验后解压)¶
| ECS | 包路径 | SHA256 | 尺寸 |
|---|---|---|---|
| 8.218 | ocm/private/deploy/mfr-portal-8218-basepath-20260828-1253.tar.gz |
e34505caa36ca7dfea6d96b8f7c21707c233678e7eb060951254c278b2716a87 |
30,166,374 B |
| 112 | ocm/private/deploy/mfr-portal-112-nobasepath-20260828-1224.tar.gz |
32bd1d86f89f2822957f3c058ad1be519f42aa26ddbc50477e6bfa631fe80db2 |
30,167,383 B |
禁用:现网跑的 buildId lmwJrmNajqxAVE3f9pD2a 旧 build(无 basePath,8.218 JS 全 404 根因)。
三、执行步骤(两 ECS 同流程,注意包不同)¶
S1(8.218 阿里云新 ECS)¶
# 1) 停止现网 mfr-portal(systemd 或 PM2,听云熟悉现场)
systemctl stop mfr-portal # 或 pm2 stop mfr-portal
# 2) 备份现网
mv /opt/dip1/dip1/frontend/apps/mfr-portal/.next /opt/dip1/dip1/frontend/apps/mfr-portal/.next.bak.$(date +%Y%m%d%H%M%S)
mv /opt/dip1/dip1/frontend/apps/mfr-portal/standalone /opt/dip1/dip1/frontend/apps/mfr-portal/standalone.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null || true
# 3) 解包(从听写 scp/rsync 接收的暂存区路径)
cd /opt/dip1/dip1/frontend/apps/mfr-portal
tar -xzf /path/to/ocm/private/deploy/mfr-portal-8218-basepath-20260828-1253.tar.gz
# 产物:standalone/(含 server.js + node_modules + .next/static + public)
# 4) sha256sum 校验包完整性
sha256sum /path/to/ocm/private/deploy/mfr-portal-8218-basepath-20260828-1253.tar.gz
# 应输出:e34505caa36ca7dfea6d96b8f7c21707c233678e7eb060951254c278b2716a87
# 5) 启动(PORT=3000,与 Caddy handle_path /mfr/* 反代对齐)
# systemd 方式:WorkingDirectory=/opt/dip1/dip1/frontend/apps/mfr-portal/standalone/apps/mfr-portal
# ExecStart=/usr/bin/env PORT=3000 node server.js
systemctl start mfr-portal # 或 pm2 start mfr-portal
S2(112 深圳旧 ECS)¶
同流程,包替换为 mfr-portal-112-nobasepath-20260828-1224.tar.gz(SHA256 32bd1d86...)。
四、验收断言(两 ECS 各跑一组)¶
| # | 断言 | 8.218 预期 | 112 预期 |
|---|---|---|---|
| V1 | curl -s -o /dev/null -w "%{http_code}" <host>/mfr/login 或 /login |
8.218: /mfr/login 200 |
112: /login 200 |
| V2 | curl -s <host>/mfr/login grep chunk src |
引用 /mfr/_next/static/chunks/*.js(带前缀) |
引用 /_next/static/chunks/*.js(无前缀) |
| V3 | curl -s -o /dev/null -w "%{http_code}" <chunk URL> |
200(不再 404) | 200 |
| V4 | 浏览器访问 MFR 登录页 → 点"一键签发开发令牌" | 跳转到 /mfr/quote(不再弹回 /login) | 跳转到 /quote |
| V5 | quote 页点击「灯具」品类卡片 | card-selected 迁移 + 工时 4.2→1.5h | 同 |
| V6 | v2-api POST /api/v2/qsv/quote/mfr-open 无 token | 401(零回归) | 401 |
| V7 | 四端 admin/wkr/cst/dl + /mfr/ 或 / | 全 200(零回归) | 同 |
V1~V3 为必过(curl 自证,回执必填);V4~V5 听写浏览器级复测复核;V6~V7 听云 curl 自证。
五、回执要求¶
完成后回传: 1. 两 ECS 各 V1~V3 + V6~V7 的 curl 输出(原文) 2. systemd/pm2 服务名 + 启动日志 tail(确认 standalone server.js 监听 :3000) 3. 部署中任何异常(完整错误原文 + 命令 + 当前目录)
六、红线¶
- 仅替换 mfr-portal standalone 目录 + 重启服务
- 不改 Caddy(@mfrNav workaround 待 8.218 稳定后由听写决策移除时机,本单不动)
- 不改 后端容器(api / api-legacy / PG)、不改 OPR-Admin/WKR/CST/DL 前端
- 不改 PG 数据、不改 env(API URL 已 build 时固化进 JS bundle,无需 env)
督办:P0 紧急,30 分钟内完成并回执。
七、回执(听云 OCM · 2026-08-28 · OCL L-20260828-04)¶
结论:S1(8.218)+ S2(112)全部完成,V1~V3 + V6~V7 双机全绿,双包 SHA256 双重校验一致。
7.1 断言结果汇总¶
| # | 断言 | 8.218 实测 | 112 实测 |
|---|---|---|---|
| V1 | 登录页 200 | /mfr/login=200 ✅ |
:3000/login=200 ✅ |
| V2 | chunk 前缀 | /mfr/_next/static/chunks/* ✅(带前缀) |
/_next/static/chunks/* ✅(无前缀) |
| V3 | chunk 200 | webpack chunk=200 ✅ | webpack chunk=200 ✅ |
| V4 | 浏览器登录跳转 | ⏳ 留听写复核 | ⏳ 留听写复核 |
| V5 | 品类卡片点击 | ⏳ 留听写复核 | ⏳ 留听写复核 |
| V6 | mfr-open 无token 401 | 401 ✅ | 401 ✅(112 :9100 实为 v2 API,端点存在) |
| V7 | 零回归 | admin/wkr/cst/dl 全 200 ✅(/mfr/=308 为 basePath 根重定向,正常) | harbor80=200 ✅(未触碰)mfr3000root=200 ✅ |
7.2 服务状态¶
| ECS | 管理方式 | 状态 |
|---|---|---|
| 8.218 | PM2 mfr-portal(id=6, pid 1049979) |
online,Ready in 179ms,:3000 |
| 112 | systemd mfr-portal.service(pid 2503671) |
active,Ready in 160ms,:3000 |
7.3 部署异常与处置(原文摘要)¶
- Windows 打包 symlink 解引用(两台均中):
apps/mfr-portal/node_modules/next|react被打成普通目录 → styled-jsx MODULE_NOT_FOUND。处置:替换为指向.pnpmstore 的 symlink(与旧备份结构一致),重启后 Ready。 - 8.218 Caddy handle_path 剥前缀与 basePath build 冲突:
/mfr/login被剥成/login转发 → Next.js 404(HTML 200 但 V1 语义失败)。处置:handle_path /mfr/*→handle /mfr/*(保留前缀)。 - bind mount inode 漂移(第 3 次复现):宿主 sed 后容器内仍旧内容,
cat >因 :ro 被拒(Read-only file system)。处置:docker rm -f dip1-prod-caddy+docker run原样重建(host 网络 + ro Caddyfile + /data + /var/log/caddy)。 - 112 凭据波折:CR-025
.local未落地;9881Zzy$与备案f7bc7f3d…均 Access denied → 用户控制台重置密码后登录成功(hostkey 未变)。 - 112 现场档案修正:systemd 管理(非 PM2);:9100 为 v2 API(170 条 /api/v2/* 路径,含 mfr-open);:80/:443 为 Harbor(未触碰)。
完整过程与 curl 原文见 OCL L-20260828-04。