跳转至

听云 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 部署异常与处置(原文摘要)

  1. Windows 打包 symlink 解引用(两台均中)apps/mfr-portal/node_modules/next|react 被打成普通目录 → styled-jsx MODULE_NOT_FOUND。处置:替换为指向 .pnpm store 的 symlink(与旧备份结构一致),重启后 Ready。
  2. 8.218 Caddy handle_path 剥前缀与 basePath build 冲突/mfr/login 被剥成 /login 转发 → Next.js 404(HTML 200 但 V1 语义失败)。处置:handle_path /mfr/*handle /mfr/*(保留前缀)。
  3. 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)。
  4. 112 凭据波折:CR-025 .local 未落地;9881Zzy$ 与备案 f7bc7f3d… 均 Access denied → 用户控制台重置密码后登录成功(hostkey 未变)。
  5. 112 现场档案修正:systemd 管理(非 PM2);:9100 为 v2 API(170 条 /api/v2/* 路径,含 mfr-open);:80/:443 为 Harbor(未触碰)。

完整过程与 curl 原文见 OCL L-20260828-04