Add WeChat service account routing with sync acks, connectivity tests, and context isolation; document deploy runbooks; and bundle related MindSpace, voice, Plaza, and server gateway changes for production rollout. Co-authored-by: Cursor <cursoragent@cursor.com>
10 KiB
Memind 生产更新发布指南
本文描述如何把本地开发代码安全发布到 g2.tkmind.cn 生产环境。
发布前请先阅读 生产 / 测试 / 预览隔离规程,避免误占生产端口或覆盖用户数据。
1. 架构与发布目标
用户访问 https://g2.tkmind.cn/ 的流量路径:
Cloudflare(橙云)
→ Cloudflare Tunnel
→ Studio Caddy(:8090,g2 负载均衡)
├─ 权重 19 → Studio Portal(127.0.0.1:8081) ← 主流量
└─ 权重 1 → 105 Portal(经隧道 127.0.0.1:18080 → :8080) ← 灰度副机
两台 Portal 都是 无状态前端,共用 Studio 上的 goosed 与 MindSpace 数据目录。
| 角色 | 机器 | 代码目录 | 服务 | 重启方式 |
|---|---|---|---|---|
| 生产主 | Studio Mac(100.99.38.66) |
/Users/john/Project/Memind |
Portal :8081、Plaza :3001 |
launchctl kickstart |
| 灰度副 | 105(经 Tailscale ssh105) |
/root/tkmind_go/ui/h5 |
goose-h5 :8080 |
systemctl restart goose-h5 |
| 负载均衡 | Studio | scripts/g2-lb.Caddyfile |
Caddy :8090 |
改权重后 caddy reload |
更详细的流量与灰度比例说明见 g2 负载均衡。
2. 目录与环境对照
| 环境 | 典型目录 | 端口 | 用途 |
|---|---|---|---|
| 生产(Studio) | /Users/john/Project/Memind |
8081 / 3001 |
线上 g2 / plaza |
| 开发预览 | /Users/john/Project/test/Memind 或本机副本 |
18081 / 13001 |
本地联调,禁止占 8081 |
| 105 副机 | /root/tkmind_go/ui/h5 |
8080 |
g2 灰度流量 |
重要: rsync_to_server.sh 会把你执行命令时所在的本地目录同步到 Studio 生产目录。发布前请确认当前目录里的代码就是你要上线的版本,而不是半成品或未验证的分支。
3. 发布入口(主流程)
推荐唯一入口: 项目根目录的 rsync_to_server.sh
cd /path/to/your/memind-repo # 开发完成、已自测的目录
# ① 预览(不修改任何远端)
./rsync_to_server.sh --dry-run
# ② 正式发布(Studio + 105 全量)
./rsync_to_server.sh
脚本会自动完成:
- 本地 Pre-flight(关键文件、安全 patch、exclude 规则)
- Studio Pre-flight(SSH、
.env、MindSpace、data 完整性) - 交互确认(可用
--yes跳过) - rsync 代码 → Studio 生产目录
- rsync 后校验(
.env未变、MindSpace 未减少、patch 仍在) - Studio 上
npm install+npm run build - 重启 Studio Portal → Plaza,并做健康检查
- 经 Studio 触发
scripts/sync-to-105.sh,同步并重启 105
4. 发布前检查清单
在 ./rsync_to_server.sh 之前,逐项确认:
4.1 本地构建与测试
pnpm install # 依赖有变更时
pnpm run build # 前端改动必须能编过
pnpm test # 建议跑;涉及核心逻辑时必跑
| 改动类型 | 是否必须 build | 能否 --skip-build |
|---|---|---|
前端(.tsx / .css / src/) |
是 | 否 |
仅后端(.mjs) |
否(但 build 无害) | 可以 |
| 仅文档 / 脚本 | 否 | 可以 |
4.2 生产在线(只读)
curl -s http://127.0.0.1:8081/api/status # Studio Portal,期望 ok
curl -s http://127.0.0.1:18080/api/status # 105 隧道,期望 ok
105 联通必须走 Tailscale,不要用公网 IP:
ssh ssh105 'echo tunnel-ok-105'
4.3 安全约束(脚本会自动检查)
server.mjs必须含WORKSPACE_MAINTENANCE_ENABLEDpatch(否则 105 重启会在 rclone 挂载上卡死).env、MindSpace/、data/在 exclude 列表中,不会被 rsync 覆盖- rsync 使用
--delete:本地已删的文件会从 Studio 删掉(exclude 外的路径)
4.4 发布范围确认
rsync_to_server.sh同步的是整个仓库(除 exclude 外),不是单个文件- 工作区若有未完成的其它改动,会一并上线——发布前建议 commit 或整理干净
- 涉及数据库迁移、批量清数据、支付回调测试等,不要直接在生产目录试跑,见 隔离规程
5. 分步与保守发布
rsync_to_server.sh 支持的常用参数:
| 参数 | 作用 | 适用场景 |
|---|---|---|
--dry-run |
只预览 diff,不改远端 | 每次正式发布前必做 |
--only-100 |
只更新 Studio,不推 105 | 先让 95% 主流量生效,105 稍后 |
--only-105 |
只触发 Studio→105 同步 | Studio 已是最新,只补 105 |
--skip-build |
跳过远端 npm run build |
纯后端改动且确认 dist 无需更新 |
--no-restart |
只同步代码,不重启服务 | 分批发布;需自行重启 |
--yes / -y |
跳过交互确认 | 自动化或你已看过 dry-run |
示例:
# 只发 Studio(主流量 95%)
./rsync_to_server.sh --only-100
# 纯 server.mjs 改动,跳过 build
./rsync_to_server.sh --skip-build
# 先同步代码,稍后再重启
./rsync_to_server.sh --no-restart
# 之后在 Studio 上手动 kickstart,或再跑一遍带重启的同步
6. 105 单独同步
若 Studio 代码已是最新,只需更新 105:
# 在 Studio 生产目录执行
cd /Users/john/Project/Memind
bash scripts/sync-to-105.sh
# 或从本地只触发 105 链路
./rsync_to_server.sh --only-105
sync-to-105.sh 会:
- rsync 代码(
--delete)与dist/到root@ssh105:/root/tkmind_go/ui/h5 - 远端
npm install+npm run build(可用SKIP_BUILD=1跳过) systemctl restart goose-h5- 校验关键文件 md5 与
:8080/api/status
环境变量(可选):
| 变量 | 默认值 | 说明 |
|---|---|---|
H5_DEPLOY_HOST |
root@ssh105 |
105 SSH 目标 |
H5_REMOTE_DIR |
/root/tkmind_go/ui/h5 |
105 代码路径 |
H5_SYSTEMD_SERVICE |
goose-h5 |
systemd 服务名 |
SKIP_BUILD |
0 |
1 跳过远端 build |
NO_RESTART |
0 |
1 不重启服务 |
package.json 中的 pnpm deploy:105 等价于本地执行 bash scripts/sync-to-105.sh(需本机能 SSH 到 105,或已在 Studio 上)。
7. 发布过程与影响窗口
全量 ./rsync_to_server.sh 典型耗时 5~10 分钟。
| 阶段 | 用户可见影响 |
|---|---|
| rsync + npm install + build | 无(旧进程仍在跑) |
| Studio Portal 重启 | 8081 短暂不可用,约 10~40 秒;g2 主流量(约 95%)可能短暂 502 |
| 105 goose-h5 重启 | 灰度流量(约 5%) 短暂不可用 |
| Plaza 重启 | plaza.tkmind.cn 可能短暂不可用;与 g2 主聊天无关 |
Caddy 会对不健康上游做 active health check,105 重启期间可能暂时从池中摘除。
8. 发布后验证
8.1 健康检查
curl -s http://127.0.0.1:8081/api/status
curl -s http://127.0.0.1:18080/api/status
curl -s https://g2.tkmind.cn/api/status
8.2 确认命中哪台上游
g2 响应头 X-Memind-Upstream:
127.0.0.1:8081→ Studio127.0.0.1:18080→ 105
curl -s -D - -o /dev/null https://g2.tkmind.cn/api/status | grep -i x-memind-upstream
8.3 业务冒烟
按本次改动选手动验证,例如:
- 打开 g2 聊天页,测试新功能
- 登录 / 微信 OAuth(若动到 auth)
- MindSpace 页面读写(若动到 pages)
- Plaza 列表(若动到 plaza)
8.4 日志
# Studio Portal
tail -f ~/Library/Logs/memind-portal.log
# Studio Plaza
tail -f ~/Library/Logs/plaza-prod.log
# 105(经 ssh105)
ssh ssh105 'journalctl -u goose-h5 -n 50 --no-pager'
9. 回滚思路
项目没有一键回滚脚本,常见做法:
- 代码回滚: 在本地 git 回到上一个 good commit,
./rsync_to_server.sh再发一版 - 仅 Studio: 若 105 有问题,可临时把 g2 权重调到 100% Studio(见 g2-load-balancing.md)
- 紧急恢复 Portal: 若 8081 挂了,见 隔离规程 · 事故恢复
发布前建议打 tag 或记录当前 commit,便于回滚:
git rev-parse HEAD
git tag -a release-2026-06-19 -m "before voice UI deploy"
10. 其它发布路径(非 g2 主站)
10.1 同步到局域网测试机
仅源码同步到 192.168.1.9 上的 test 目录,不是生产:
bash scripts/deploy-to-test-host.sh --dry-run
bash scripts/deploy-to-test-host.sh
目标:test-memind / test-memindadm / test-memindplaza。同步后需按该机习惯手动重启服务。
10.2 Plaza 105 静态站
pnpm deploy:plaza-105
依赖 goose-h5 已部署(pnpm deploy:105 或全量 rsync)。详见 Plaza 本机部署。
10.3 已废弃 / 不可用
| 命令 | 状态 |
|---|---|
pnpm deploy:prod |
指向 ../../deploy/deploy-h5-prod.sh,当前仓库旁路不存在,勿用 |
11. 推荐发布 SOP(标准作业)
适合大多数功能迭代的固定步骤:
1. 在测试端口完成开发与自测(18081,勿占 8081)
2. pnpm run build && pnpm test
3. ./rsync_to_server.sh --dry-run ← 看清将要同步什么
4. 确认无多余改动、无数据库破坏性操作
5. ./rsync_to_server.sh ← 全量 Studio + 105
6. curl 健康检查 + 浏览器冒烟
7. 观察 5~10 分钟日志,确认无 ERROR 尖峰
保守版(先主后副):
1~4 同上
5. ./rsync_to_server.sh --only-100
6. 冒烟通过后
7. ./rsync_to_server.sh --only-105
12. 相关文档
| 文档 | 内容 |
|---|---|
| service-isolation-runbook.md | 生产 / 测试端口隔离、禁止事项、事故恢复 |
| g2-load-balancing.md | g2 权重、105 隧道、灰度比例调整 |
| local-dev.md | 本地开发端口与 preview |
| plaza-local.md | Plaza 部署与 Tunnel |
维护说明: 若部署脚本路径、主机名或 systemd 服务名变更,请同步更新本文与 rsync_to_server.sh 头部注释。