XuqmGroup-PrivateDeploy/docs/runbook.md
徐勤民 dde3f9ece7 docs: 整理全量文档
- README: 补充 reset.sh 快速入口和脚本对比表
- runbook: 新增「容器重置」章节和「故障排查」(502/crash-loop/WebSocket/镜像未生效)
- configuration: 修正端口表(im=11228/push=11229/update=11230/license=11231),
  补充 SPRING_DATASOURCE_PASSWORD 设计说明,移除已废弃的 environment 密码块说明
- acceptance-checklist: 修正端口号,补充 WebSocket 多层透传说明,移除不存在的 11227 行
- deployment-defaults: 同步端口表,补充 reset.sh 和 WebSocket 注意事项

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 11:48:45 +08:00

6.6 KiB

私有化部署运行手册

一键部署

curl -fsSL https://xuqinmin.com/xuqmGroup/XuqmGroup-PrivateDeploy/raw/branch/main/install.sh \
  -o install.sh && bash install.sh

交互式向导依次完成:

  1. 选择租户初始化方式(新建 / 迁移)
  2. 填写租户信息或迁移密钥
  3. 填写外部访问地址(上层 nginx 对外的域名/IP,用于 SDK 配置)
  4. 自动完成容器启动、数据库初始化、全量验证

完成后按输出的端口表配置宿主机 nginx。


Nginx 配置

部署向导会询问宿主机是否已有 nginx,根据答案自动选择绑定模式

场景一:无宿主机 nginx多层代理 / 内网服务器)

容器直接绑定宿主机 0.0.0.0:80NGINX_BIND=80),上层 nginx 直接指向本机 IP

location / {
    proxy_pass         http://<部署服务器IP>;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 3600s;
}

场景二:宿主机已有 nginx云服务器域名 HTTPS

容器绑定 127.0.0.1:11223NGINX_BIND=127.0.0.1:11223),宿主机 nginx server 块加一条:

location / {
    proxy_pass         http://127.0.0.1:11223;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 3600s;
}

每一层 nginx 代理都必须加 proxy_http_version 1.1Upgrade/Connection 头,缺少任意一层 IM WebSocket 就会断开。

内置 nginx 路由配置在 config/nginx/conf.d/xuqm.conf,使用 Docker 服务名动态路由,容器重建后无需重载 nginx。


端口说明

宿主机端口 说明
80 内置 nginx 入口(无宿主机 nginx 场景,NGINX_BIND=80
11223 内置 nginx 入口(有宿主机 nginx 场景,NGINX_BIND=127.0.0.1:11223
11224–11231 各业务容器(绑定 127.0.0.1,仅调试用)

各业务容器端口仅用于直接调试,正常流量全部走内置 nginx 入口。


日常运维

升级

curl -fsSL https://xuqinmin.com/xuqmGroup/XuqmGroup-PrivateDeploy/raw/branch/main/upgrade.sh \
  -o upgrade.sh && bash upgrade.sh

保留全部数据和配置,自动修复已知配置问题,可选拉取新镜像,完成后运行全量验证。

容器重置(保留数据)

容器状态异常时502、crash-loop、密码错误执行

bash scripts/reset.sh

彻底重建所有容器并拉取最新镜像,不删除数据卷,不修改配置文件。如只想重建容器而不拉取镜像:

bash scripts/reset.sh --no-pull

常用命令

# 查看所有容器状态
docker compose -f docker-compose.yml -f docker-compose.infra.yml ps

# 查看服务日志(替换 tenant-service 为目标服务名)
docker compose -f docker-compose.yml -f docker-compose.infra.yml logs --tail 100 tenant-service

# 重新运行全量验证
bash scripts/verify.sh

# 停止所有服务(保留数据)
docker compose -f docker-compose.yml -f docker-compose.infra.yml down

# 启用可选服务
bash scripts/enable-service.sh im

# 禁用可选服务(不删数据)
bash scripts/disable-service.sh im

# 备份数据
bash scripts/backup.sh

# 恢复数据
bash scripts/restore.sh <backup-file>

租户迁移

迁移通过一键部署向导完成,选择「迁移租户」后:

  1. 前往公有化平台控制台 → 安全中心 → 私有化部署迁移 → 生成迁移密钥
  2. pmk_ 开头的密钥粘贴进向导
  3. 脚本自动导出租户数据、导入私有库、写入 license 记录、重启服务

迁移为单租户操作,会清空现有 bootstrap 数据后写入迁移数据。


数据目录

路径 说明
data/mysql/ MySQL 数据文件
data/redis/ Redis AOF 文件
data/uploads/ 文件服务上传目录
data/update/ 版本管理包存储
data/backups/ 备份文件
logs/ 审计日志

故障排查

nginx 返回 502

现象:所有接口返回 502,容器状态正常。
原因nginx 缓存了旧容器 IP,容器重建后 IP 变更未同步。
处理

bash scripts/reset.sh --no-pull

内置 nginx 配置已使用 Docker DNS 动态解析(resolver 127.0.0.11 valid=10s),重置后新容器 IP 会自动生效,无需手动 reload。


服务 crash-loop / 启动失败

现象docker compose ps 显示服务 Restarting,日志反复出现启动异常。
处理:先查日志确认原因:

docker compose -f docker-compose.yml -f docker-compose.infra.yml logs --tail 50 <服务名>

常见原因及处理:

日志关键字 原因 处理
Access denied ... (using password: NO) secrets.env 缺少 SPRING_DATASOURCE_PASSWORD 执行 bash scripts/reset.sh,脚本会自动补齐
Communications link failure MySQL 尚未就绪 等待约 30s 后自动恢复,或执行 reset
NOAUTH Authentication required secrets.env 缺少 SPRING_DATA_REDIS_PASSWORD 执行 bash scripts/reset.sh
host not found in upstream nginx 启动时 DNS 解析失败 确认其他容器正常启动后执行 reset

IM WebSocket 连接失败426 / 502

现象:浏览器控制台 WebSocket 握手返回 426 或 502。
排查顺序

  1. 确认每一层 nginx 都有 proxy_http_version 1.1 + Upgrade/Connection
  2. 确认 im-service 容器正常运行:docker compose ps im-service
  3. 确认镜像版本包含私有化 CORS 修复(DEPLOYMENT_MODE=PRIVATE 放开所有 Origin
# 检查 im-service 是否健康
curl -s http://127.0.0.1:11228/actuator/health

升级后镜像未生效

现象:更新了镜像但服务行为未变化。
原因docker compose restart 不会应用新镜像,需 up -d 触发重建。
处理

bash scripts/reset.sh   # 拉取最新镜像并重建所有容器

SDK 地址仍指向公有化平台

现象config/sdk/xuqm-private-sdk.jsonconfig/xuqm.env 中仍有 xuqinmin.com 地址。
处理

bash scripts/update.sh   # 自动检测并修正 SDK URL