Files
sub2api-cn-relay-manager/docs/REMOTE43_OPERATIONS_BASELINE.md
phamnazage-jpg 47ced19c7b fix(deploy): production CRM deployment improvements
- Fix deploy_crm_only.sh: non-destructive hot reload
  - Enhanced stop logic with pgrep + fuser for port release
  - Added 3-layer verification (process/control/user)
  - Check /proc/$pid/exe for (deleted) marker
  - Never delete DB

- Fix portal script contracts: crm_session → crm_subject
  - deploy_tksea_portal.sh: use $cookie_crm_subject
  - test_tksea_portal_assets.sh: assert crm_subject exists
  - nginx.example.conf: updated trusted subject header

- Add systemd service management
  - sub2api-crm.service.template
  - install_crm_systemd.sh
  - verify_crm_deployment.sh

Update docs/plans/2026-06-04-next-version-plan.md with deployment findings.
2026-06-10 15:44:45 +08:00

8.4 KiB
Raw Blame History

remote43 运维基线2026-06-10

1. 目标

这份文档用于回答三件事:

  1. remote43 当前到底跑着什么
  2. 为什么“更新部署经常看起来成功、实际没切过去”
  3. 后续持续运维必须遵守哪些规则

这是当前真相源,优先于零散会话结论。

2. 服务器画像

主机

  • Host: ubuntu@43.155.133.187
  • Hostname: VM-0-16-ubuntu
  • OS: Ubuntu / Linux 6.8.0-107-generic
  • CPU: 2 vCPU
  • Memory: 3.6 GiB
  • Swap: 1.9 GiB
  • Root disk: 59G, 已用 34G, 使用率 59%

当前负载2026-06-10 09:25 CST 只读巡检)

  • load average: 3.16 3.39 3.40
  • 可用内存仅 259 MiB
  • swap 已使用 982 MiB
  • memory PSI / io PSI 持续非零,存在资源压力

主要监听端口

  • 80 / 443 → nginx
  • 8080 → sub2api host
  • 127.0.0.1:18190 → CRM

4. 当前运行面真相

最后更新: 2026-06-10

CRM 当前状态

  • 运行目录: /home/ubuntu/crm-only-20260602_18190
  • 当前进程 PID: 920892 (systemd 管理)
  • 当前运行命令: ./sub2api-cn-relay-manager-server
  • /proc/920892/exe 指向:
    • /home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager-server (无 deleted 标记)
  • Portal Session: login_enabled: true

CRM 健康与管理接口

  • GET /healthzok
  • GET /api/packs + admin token → HTTP 200

这表示:

  • CRM 当前不是完全挂掉
  • 问题核心是“部署切换失败”,不是“服务不可用”

CRM 数据库

  • 文件:/home/ubuntu/crm-only-20260602_18190/sub2api-cn-relay-manager.db
  • 当前快速计数2026-06-10 巡检时):
    • hosts = 0
    • logical_groups = 0
    • logical_group_routes = 0
    • user_keys = 0
    • schema_migrations = 17

注意:当前 DB 已不是“有完整生产业务数据的状态库”,至少在该时点已经接近空库。

4. 当前仓库/部署目录事实

远端 repo

  • 路径:/home/ubuntu/sub2api-cn-relay-manager-git-current
  • HEAD: 4ec9dad44f6768368c2aa782ed96d36355709823
  • git status --short 发现:
    • ?? sub2api-crm-server

说明:

  • 远端 repo 不是完全干净
  • 存在未纳管二进制残留

CRM 目录关键文件

  • .env.crm2026-06-09 21:28 更新
  • sub2api-crm-server-gateway2026-06-09 21:28 上传
  • sub2api-cn-relay-manager-server2026-06-06 10:39 旧文件
  • crm.log:最新内容只有一条启动失败日志
  • crm.pid2026-06-09 21:28 写入

5. 已确认的部署失败根因链

根因 1旧进程没有真正退掉

证据:

  • 18190 被旧进程 54164 占用
  • 新 bootstrap 之后 crm.log 明确报:
    • listen tcp 127.0.0.1:18190: bind: address already in use

结论:

  • 新进程没有启动成功
  • 旧进程继续服务,造成“部署看起来成功、实际没切换”

根因 2deploy_crm_only.sh 不是生产热更新脚本

证据:

  • scripts/deploy/deploy_crm_only.sh:138
    • rm -f "$CRM_DB_FILE" "$CRM_LOG_FILE"
  • scripts/deploy/deploy_crm_only.sh:205
    • 远端清理时也删除 REMOTE_CRM_DB_FILE

结论:

  • 该脚本会删除 SQLite DB
  • 它适合“重建栈”,不适合“保状态热更新”

根因 3CRM 启动方式仍然脆弱

证据:

  • scripts/deploy/deploy_crm_only.sh:140
    • nohup bash -lc 'set -a; source "$CRM_ENV_FILE"; set +a; exec "$CRM_BINARY"'

结论:

  • 这是已知脆弱模式
  • 即使这次主要失败是端口占用,这个模式本身也不应继续作为生产标准

已修复portal 部署脚本和测试门禁已修正契约

原问题:

  • scripts/deploy/deploy_tksea_portal.sh 曾使用 $cookie_crm_session
  • scripts/test/test_tksea_portal_assets.sh 曾断言 $cookie_crm_session,并排斥 $cookie_crm_subject

修复(本轮完成):

  1. deploy_tksea_portal.sh 已改为 $cookie_crm_subject
  2. test_tksea_portal_assets.sh 已改为断言 $cookie_crm_subject 存在、$cookie_crm_session 不存在
  3. nginx.sub.tksea.top.conf.example 已同步更新
  4. 测试门禁已通过:bash scripts/test/test_tksea_portal_assets.sh → PASS

6. 资源与容量风险

高风险:内存压力

证据:

  • 机器总内存 3.6 GiB
  • 可用仅 259 MiB
  • swap 已用近 1 GiB
  • Top RSS:
    • gitea web 占用约 2.45 GiB RSS

结论:

  • 当前机器资源最重的不是 CRM而是 Gitea
  • remote43 已处于“高内存压力 + 持续 swap”状态
  • 这会放大部署时序问题、I/O 抖动、git/编译/解压失败概率

中风险:孤儿/历史进程与残留栈

证据:

  • 存在 /tmp/sub2api-crm-static-verify
  • 存在多个 /app/sub2api
  • 存在 quarantine / tokens-reef / 临时目录残留

结论:

  • remote43 不够“单一生产真相”
  • 存在历史验证栈、遗留进程、临时产物共存

7. 备份与恢复现状

当前看到的备份更多是“人工备份痕迹”,不是制度化备份:

  • sub2api-cn-relay-manager.db.bak.20260608_*
  • trusted-subject-backup-20260609_173034/

缺口:

  • 没看到定时数据库备份作业
  • 没看到统一的保留策略
  • 没看到恢复演练记录

8. 未来持续运维规则(强制)

R1. 生产 CRM 只能走“非破坏性热更新”

禁止:

  • 删除生产 SQLite DB
  • 用“重建栈脚本”直接覆盖生产
  • 不确认旧 PID 已退出就启动新进程

必须:

  1. 记录当前 PID / 二进制 sha256 / DB 文件时间
  2. 停旧进程并确认 18190 已释放
  3. 上传新二进制
  4. 启动新进程
  5. 验证:
    • healthz=ok
    • 管理接口 200
    • readlink /proc/$pid/exe 指向新二进制,且不带 (deleted)

R2. 生产脚本禁止删除 DB

任何生产 deploy 脚本都不得包含:

  • rm -f "$CRM_DB_FILE"
  • rm -f "$REMOTE_CRM_DB_FILE"

如确需重建数据库:

  • 必须单独命名为 destructive/rebuild 脚本
  • 必须显式要求人工确认

R3. CRM 必须纳入明确监督器

当前状态:

  • CRM 不是 systemd service
  • 只是一个 pidfile + nohup 进程

后续规则:

  • 生产 CRM 必须迁移到以下二选一:
    1. systemd service
    2. 明确的进程监督器(且有 status/restart/log 统一入口)

目标:

  • 避免 (deleted) ELF 长期运行
  • 避免 pidfile 漂移
  • 避免人工 kill/start 时序错误

R4. 部署脚本、示例、测试门禁必须共享同一契约

当前关键契约:

  • trusted subject 来源必须是 $cookie_crm_subject
  • 不能再使用 $cookie_crm_session

规则:

  • 文档改了deploy script 和 test gate 必须同改
  • 任何一个仍保留旧契约,都不允许宣称闭环

R5. 每次部署后必须做“三层验证”

  1. 进程层
  • 监听端口正确
  • PID 正确
  • /proc/$pid/exe 不带 (deleted)
  1. 控制面层
  • /healthz = ok
  • GET /api/packs = 200
  1. 用户面层
  • GET /api/portal/session
  • create/chat/pause/resume/delete 全链路

R6. remote43 要建立单一真相目录

建议长期保留:

  • 一个生产 CRM root
  • 一个生产 repo root
  • 一个 runbook 路径
  • 一个 backup 路径

禁止长期保留大量含糊用途目录:

  • 多个临时验证 root 并存
  • 不说明用途的 quarantine / tmp 二进制常驻

R7. 建立最低备份制度

至少包括:

  1. SQLite DB 定时备份
  2. nginx site 配置备份
  3. .env.crm 备份
  4. 最近 N 份保留策略
  5. 一次真实恢复演练

R8. 资源治理规则

  • Gitea 当前是最大内存消费者,后续任何“服务器变慢/部署异常”都要先看它
  • 当 available memory < 300MiB 或 swap 持续增长时,禁止在 remote43 直接进行重编译/大规模解包
  • 生产构建优先本地 build 后上传成品,而不是远端现编

9. 推荐后续动作(按优先级)

P0

  1. scripts/deploy/deploy_crm_only.sh
    • 去掉删 DB
    • 改成真正 hot-update
    • 启动后验证新 PID 与新 exe
  2. scripts/deploy/deploy_tksea_portal.sh
    • 改成 $cookie_crm_subject
  3. scripts/test/test_tksea_portal_assets.sh
    • 门禁改成断言 $cookie_crm_subject

P1

  1. 为 CRM 增加 systemd service
  2. 增加数据库定时备份脚本与保留策略
  3. 增加部署后自动 smoke 验证脚本

P2

  1. 清理 remote43 历史验证残留目录/进程
  2. 评估 Gitea 内存占用与迁移/限额策略

10. 当前结论

  • remote43 不是“服务挂了”,而是“部署切换机制不可靠”
  • 生产 deploy 脚本当前不满足持续运维标准
  • 未来必须把“部署、监督、备份、门禁、资源治理”五件事制度化,不能继续靠临时脚本和人工记忆