Skip to content

Upgrade Guide

李源炳 edited this page Jun 19, 2026 · 1 revision

升级指南

本文档介绍如何将 IMBoy 从旧版本升级到新版本。


升级前必读

  1. 备份数据库,升级前务必执行:
    cd imboy/deploy
    bash ../scripts/backup_pg.sh
  2. 阅读目标版本的 CHANGELOG,确认是否有破坏性变更。
  3. 升级操作建议在维护窗口执行,预计停机 1–5 分钟。

标准升级流程(Docker Compose)

# 1. 拉取最新镜像
docker compose -f docker-compose.prod.yml pull

# 2. 停止当前服务
docker compose -f docker-compose.prod.yml down

# 3. (可选)备份配置文件
cp .env .env.backup.$(date +%Y%m%d)

# 4. 启动新版本
docker compose -f docker-compose.prod.yml up -d

# 5. 验证
docker compose -f docker-compose.prod.yml ps
curl http://localhost:8080/health

数据库迁移在服务启动时自动执行(由 erlang_migrate 管理,按版本号顺序幂等运行)。


验证升级成功

# 查看后端版本
curl http://localhost:8080/version

# 确认迁移已运行
docker compose exec postgres psql -U imboy -c \
  "SELECT version_id, applied_at FROM schema_migrations ORDER BY applied_at DESC LIMIT 5;"

# 检查关键日志(无 ERROR 级别日志)
docker compose logs imboy --since=5m | grep -i error

版本特定迁移说明

v1.x → v2.x

⚠️ 包含破坏性变更:数据库 schema schema_migrations 版本号格式从时间戳迁移到 8 位序号。

升级前在旧数据库执行(一次性操作):

-- 将旧时间戳版本号映射到新 8 位序号
UPDATE schema_migrations SET version_id = '00000001' WHERE version_id = '20240101120000';
UPDATE schema_migrations SET version_id = '00000002' WHERE version_id = '20240115083000';
-- 按 CHANGELOG 中的映射表依次执行

完整映射表见 CHANGELOG.md v2.0.0 章节。


回滚

# 回滚到上一个镜像版本
docker compose -f docker-compose.prod.yml down

# 编辑 docker-compose.prod.yml 将 image tag 改为旧版本
# 例:image: ghcr.io/imboy-pub/imboy:v1.5.2

docker compose -f docker-compose.prod.yml up -d

数据库迁移不会自动回滚。如需回滚迁移,从备份恢复数据库(见 scripts/restore_pg.sh)。


高可用集群升级(滚动升级)

Kubernetes 环境下 Helm 升级默认使用滚动更新,不需要停机:

helm upgrade imboy imboy/imboy \
  --namespace=imboy \
  --set image.tag="v2.0.0"

# 观察滚动更新进度
kubectl rollout status deployment/imboy -n imboy

常见升级问题

Q: 升级后服务启动失败,日志报 migration failed
A: 检查旧版数据库中是否有脏数据;运行 SELECT * FROM schema_migrations WHERE status = 'failed'; 排查失败迁移,手动修复后重启服务。

Q: 前端显示 API 版本不匹配
A: 后端/前端需同时升级;Caddy 可能缓存了旧版静态文件,执行 docker compose restart caddy 清除缓存。

Q: WebSocket 连接断开且无法重连
A: 正常现象,升级期间所有 WS 连接会断开;客户端会自动重连(约 5–30 秒)。

Clone this wiki locally