首页 产品 为什么选 OCTO 解决方案 文档 关于
文档中心 / 部署运维 / 升级与版本迁移
← 返回文档中心

升级与版本迁移

OCTO 文档中心 · 部署运维

  • octo-deployment/docker/docker-compose.yaml
  • octo-deployment/docker/README.md
  • octo-deployment/docker/scripts/init-extra-dbs.sh
  • octo-deployment/docker/scripts/docs-migrate-entrypoint.sh
  • octo-deployment/docker/scripts/search-upgrade.sh
  • octo-deployment/docker/scripts/speech-setup.sh
  • octo-deployment/helm/README.md
  • octo-deployment/helm/octo/Chart.yaml (v0.4.5)
  • octo-deployment/helm/octo/templates/job-drive-migrate.yaml
  • octo-deployment/helm/octo/templates/deployment-server.yaml
  • octo-deployment/releases/v0.2.x/v0.2.0.md

OCTO 升级与版本迁移指南 v1.0

适用版本:v0.1.x → v0.2.x,以及同代小版本升级(PATCH/MINOR)

部署形态:Docker Compose 单机部署 + Helm/Kubernetes 部署

最后更新:2026-09-22


目录

  1. [升级原则与注意事项](#1-升级原则与注意事项)
  2. [Docker Compose 升级流程](#2-docker-compose-升级流程)
  3. [Helm/Kubernetes 升级流程](#3-helmkubernetes-升级流程)
  4. [数据库迁移机制](#4-数据库迁移机制)
  5. [回滚流程](#5-回滚流程)
  6. [版本兼容性](#6-版本兼容性)
  7. [各模块升级注意事项](#7-各模块升级注意事项)
  8. [升级后验证清单](#8-升级后验证清单)
  9. [故障恢复 SOP](#9-故障恢复-sop)

1. 升级原则与注意事项

1.1 备份前置原则

备份对象 备份方式 存储位置
MySQL 数据库 mysqldump 全量导出 升级主机以外的安全路径
MinIO 对象存储 文件系统快照或 mc mirror 独立存储
配置文件 .env、docker-compose.yaml、values-*.yaml Git 仓库或版本化目录
命名卷数据(可选但推荐) docker run --rm -v :/data -v $(pwd):/backup busybox tar czf /backup/.tar.gz -C /data . 备份目录

红线:未完成备份前,不得执行 `docker compose pull` 或 `helm upgrade`。

1.2 阅读 Changelog

  1. 查阅 [octo-deployment Releases](https://github.com/Mininglamp-OSS/octo-deployment/releases) 获取当前版本到目标版本的 Release Notes。
  2. 对比 `.env.example`(docker-compose 路径下)或 `values.yaml` 新旧版本,识别新增/废弃的环境变量。
  3. 关注 Breaking Changes 章节(如有)。OCTO 遵循 SemVer,MAJOR 版本升级必然包含不兼容变更。

⚠️ 待确认(需查 release notes):各版本间 breaking changes 完整列表请以 GitHub Release 页面为准。本指南仅记录从源码中可直接确认的变更。

1.3 灰度升级建议

  • 生产环境必须先在隔离的测试环境完整演练升级流程。
  • Helm 部署建议使用 helm diff upgrade 预览变更后再执行。
  • 核心服务(octo-server、MySQL、Redis、WuKongIM、MinIO)升级期间预期有短暂服务中断;nginx 前端可保持运行但后端 API 将返回 502。
  • 对于多副本 Helm 部署,利用滚动更新策略(默认 RollingUpdate)可实现零停机,但数据库迁移阶段仍建议在维护窗口执行。

1.4 升级窗口建议

  • 选择业务低峰期(通常为夜间或周末)。
  • 预计耗时:同代 PATCH 升级约 5-15 分钟;MINOR 升级(含数据库迁移)约 15-45 分钟;MAJOR 升级或首次开启 search 模块约 30-90 分钟(取决于消息历史量)。
  • 提前通知用户维护窗口。

2. Docker Compose 升级流程

2.1 前置备份

cd /path/to/octo-deployment/docker

# 1) 备份 .env 和 docker-compose.yaml
cp .env ".env.backup.$(date +%Y%m%d%H%M)"
cp docker-compose.yaml "docker-compose.yaml.backup.$(date +%Y%m%d%H%M)"

# 2) 备份 MySQL 数据库(全量 dump)
docker compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysqldump -u root \
  --single-transaction --routines --triggers \
  --databases octo octo_summary octo_speech octo_docs octo_marketplace' \
  > "octo-mysql-backup-$(date +%Y%m%d%H%M).sql"

# 3) 备份 MinIO 数据(使用 mc mirror,或直接备份卷)
docker run --rm -v octo_minio-data:/data -v $(pwd):/backup busybox \
  tar czf "/backup/minio-backup-$(date +%Y%m%d%H%M).tar.gz" -C /data .

# 4) 备份其他关键卷(可选但推荐)
for vol in mysql-data redis-data wukongim-data server-logs; do
  docker run --rm -v "octo_${vol}:/data" -v $(pwd):/backup busybox \
    tar czf "/backup/${vol}-backup-$(date +%Y%m%d%H%M).tar.gz" -C /data .
done

注意:卷名前缀受 `COMPOSE_PROJECT_NAME` 影响,默认为 `octo_`;如果您自定义了项目名,请相应替换。

2.2 获取新版本

# 方式 A:通过 git pull 获取最新编排文件
cd /path/to/octo-deployment
git fetch --tags
git checkout   # 例如 v0.2.0
cd docker

# 方式 B:手动下载新版 docker-compose.yaml 和 .env.example
# wget https://raw.githubusercontent.com/Mininglamp-OSS/octo-deployment//docker/docker-compose.yaml
# wget https://raw.githubusercontent.com/Mininglamp-OSS/octo-deployment//docker/.env.example

2.3 对比 .env 变化

# 对比新旧 .env.example,找出新增/废弃/变更的变量
diff -u .env.backup.YYYYMMDDHHMM .env  # 如果已有备份
# 或对比官方 .env.example
diff -u <(git show HEAD~1:docker/.env.example 2>/dev/null || true) .env.example

# 关键检查点:
# - 是否有新增的必填变量(如新版本新增的 OCTO_SEARCH_*、OCTO_NOTIFY_INTERNAL_TOKEN 等)
# - 是否有变量被废弃或重命名
# - 镜像 tag 变量(OCTO_SERVER_IMAGE、OCTO_WEB_IMAGE 等)是否有变化

2.4 拉取新镜像

cd /path/to/octo-deployment/docker
docker compose pull

2.5 执行升级重启

# 标准升级:重启所有服务
docker compose up -d

# 如果仅升级核心服务(nginx 配置无变化时):
# docker compose up -d octo-server web admin nginx redis mysql
preflight → mysql → minio-init → octo-server → nginx → web/admin
         → redis ↗     wukongim ↗
  • preflight 会校验 OCTO_NOTIFY_INTERNAL_TOKEN 和 OCTO_WUKONGIM_MANAGER_TOKEN 未使用占位符。
  • init-extra-dbs.sh 仅在 MySQL 数据卷首次初始化时执行;升级时不会重复运行。新增模块(如 marketplace、speech、docs)的数据库预配使用独立的 one-shot 服务(market-preflight 等)。

2.6 观察日志

# 实时查看所有服务日志
docker compose logs -f

# 重点关注 octo-server 启动日志(含自动迁移信息)
docker compose logs -f octo-server

# 检查各服务健康状态
watch -n 5 'docker compose ps'
  • docker compose ps 所有服务状态为 healthy 或 running(one-shot 服务为 exited (0))。
  • octo-server 日志中出现监听端口 8090 启动成功的消息,无 FATAL/ERROR 级迁移错误。
  • wukongim 日志显示 manager API 已启动。

2.7 健康检查验证

# 核心 API 健康检查
curl -sk https://:/api/v1/health
# 或 HTTP
curl -s http://:/v1/ping

# 预期返回 HTTP 200 及 JSON 健康状态
# 登录页可访问
curl -sk -o /dev/null -w '%{http_code}' https://:/
# 预期:200

# Admin 控制台
curl -sk -o /dev/null -w '%{http_code}' https://:/admin/
# 预期:200(或 302 跳转登录)

3. Helm/Kubernetes 升级流程

3.1 更新 Helm 仓库/获取新 Chart

# 如果使用 Helm repo
helm repo update
helm search repo octo --versions

# 如果使用本地 chart
cd /path/to/octo-deployment/helm
git fetch --tags
git checkout 

3.2 预览变更(强烈推荐)

# 安装 helm-diff 插件(如未安装)
helm plugin install https://github.com/databus23/helm-diff

# 预览升级差异
helm diff upgrade octo ./octo \
  --namespace  \
  -f values-config.yaml \
  -f values-images.yaml \
  -f values-secrets.yaml

# 仔细检查:
# - 镜像 tag 变化
# - ConfigMap 变更
# - 新增/移除的 Deployment/Job/Service
# - 资源限制变化

3.3 前置备份

# 备份当前 release 状态
helm get values octo -n  -o yaml > "values-backup-$(date +%Y%m%d%H%M).yaml"
helm get manifest octo -n  > "manifest-backup-$(date +%Y%m%d%H%M).yaml"

# 备份数据库(通过 port-forward 或 exec 到 MySQL pod)
kubectl port-forward -n  svc/mysql 33306:3306 &
MYSQL_PWD="" mysqldump -h 127.0.0.1 -P 33306 -u root \
  --single-transaction --routines --triggers \
  --databases octo octo_summary octo_speech octo_docs octo_marketplace octo_drive \
  > "octo-mysql-backup-$(date +%Y%m%d%H%M).sql"
kill %1  # 关闭 port-forward

# 备份 MinIO/PVC 数据(按集群存储策略执行快照)

3.4 合并新 values

# 对比 chart 默认 values 变更
diff <(helm show values ./octo --version ) <(helm show values ./octo --version )
  • drive 模块:v0.2.0 新增 drive,启用时需要 drive.enabled: true 和 DRIVE_DB_PASSWORD。
  • docs 模块:启用时需要 docsBackend.enabled: true 和 OCTO_DOCS_DB_PASSWORD、OCTO_DOCS_NOTIFY_TOKEN。
  • marketplace:需要 marketplace.enabled: true 和 OCTO_MARKETPLACE_DB_PASSWORD。
  • search 模块:需要配置 OCTO_SEARCH_BACKEND、Kafka 和 OpenSearch 相关参数。

3.5 执行升级

helm upgrade octo ./octo \
  --namespace  \
  -f values-config.yaml \
  -f values-images.yaml \
  -f values-secrets.yaml \
  --timeout 10m \
  --wait
  1. 先执行 pre-upgrade hooks(包括 `drive-migrate` Job 等迁移任务)。
  2. 按 Deployment 滚动更新顺序替换 Pod。
  3. 等待所有 Pod ready。
组件 类型 作用
octo-server initContainer wait-for-mysql/redis/minio 等待依赖服务就绪
octo-server initContainer minio-bootstrap MinIO bucket 和用户初始化
drive pre-upgrade Job drive-migrate 执行 SQL 迁移(使用 golang-migrate)
drive initContainer create-db-and-user 创建 octo_drive 库和用户
search-kafka-init Job Kafka topic 初始化
doc-indexer-backfill Job 文档索引回填

⚠️ 注意:drive 模块的迁移是通过 `helm.sh/hook: pre-upgrade` Job 执行的,在 workload 更新前运行。确保 MySQL 在升级前可访问。

3.6 验证升级结果

# 检查 Pod 状态
kubectl get pods -n  -w

# 检查 Helm release 状态
helm status octo -n 
helm history octo -n 

# 检查迁移 Job 是否成功
kubectl get jobs -n 
kubectl logs job/ -n 

4. 数据库迁移机制

4.1 自动迁移(启动时执行)

  • 迁移方式:内嵌 gorp/GORM migration,服务启动时自动执行。
  • 触发时机:每次 octo-server 容器启动。
  • 迁移范围:主库 octo 的所有表(包括 message 分表、octo_etl_es_cursor 等)。
  • 安全性:迁移为前向兼容(ALTER TABLE ADD COLUMN 等),通常为幂等操作。
  • 风险点:大表加列/加索引可能导致锁表,大版本升级需在低峰期执行。
  • 迁移方式:内嵌自动迁移。
  • 数据库:octo_summary。
  • 触发时机:服务启动时。
  • 迁移方式:内嵌自动迁移。
  • 数据库:octo_marketplace。
  • 预配:docker-compose 环境下由 market-preflight 容器(每次启动执行,幂等)完成 CREATE DATABASE/USER/GRANT。
  • 迁移方式:内嵌自动迁移。
  • 数据库:octo_speech。
  • 用户预配:首次初始化由 init-extra-dbs.sh 完成;后续升级通过 speech-setup.sh 手动执行。

4.2 init-extra-dbs.sh(仅首次初始化)

  1. 校验密码强度(拒绝占位符、字面默认值、特殊字符)。
  2. 创建数据库:`octo_summary`、`octo_speech`、`octo_docs`、`octo_marketplace`。
  3. 创建服务账号并授权:`summary`(octo_summary 全权限)、`summary_reader`(主库只读)、`marketplace`(octo_marketplace 全权限)。
  4. 条件性创建:如果设置了 `SPEECH_DB_PASSWORD`,创建 `speech` 用户;如果设置了 `OCTO_DOCS_DB_PASSWORD`,创建 `docs` 用户。

⚠️ 关键注意:此脚本只在 MySQL 卷首次初始化时运行。升级时不会重复执行。如果新版本新增了数据库或用户,需要手动执行 SQL 或通过专用 preflight 容器处理(参见 `market-preflight` 模式)。

4.3 docs 模块专用迁移入口

  1. 基础 schema 引导(幂等):检查 `doc_meta` 表是否存在;不存在则导入 `schema.sql`。
  2. 增量迁移:执行 `node dist/db/migrate.js`,应用 `/app/migrations/upgrades/` 下所有待执行迁移,使用 advisory lock + schema_migrations 表记录版本。
  3. 启动 API 服务:`exec node dist/index.js`。

4.4 drive 模块迁移(Helm)

  1. init-container `wait-for-mysql`:等待 MySQL 就绪。
  2. init-container `create-db-and-user`:创建 `octo_drive` 库和 `drive` 用户。
  3. 主容器执行 `migrate -path=/migrations -database=mysql://... up`。

⚠️ Docker Compose 环境下的 drive 迁移:drive-config init 服务负责渲染配置,schema 迁移由 drive 服务自身在启动时执行(具体机制待确认,建议首次启动观察日志)。

4.5 search 模块的特殊升级路径

no search
  → (1) docker compose --profile search up -d   (启动 Kafka/OpenSearch/indexer)
  → (2) seed searchetl cursor 到各分表 MAX(id)    [Gate G1]
  → (3) 打开实时 producer(重启 octo-server)      [Gate G2]
  → (4) 历史消息回填 + reconcile 校验             [Gate G3]
  → (5) 绑定读别名 → 物理 index                  [Gate G4]
  → (6) 切换 octo-server reader 到 es + 重启      [Gate G5]
search live
  • 先开 producer 再回填:cursor 已 seed 到高水位线,producer 只推增量,不会重复推送历史消息。
  • ES doc _id = message_id:回填和实时流的写入是幂等 upsert,重叠安全。
  • 5 个 Gate:每步都有退出码校验,脚本可从任意步恢复(--from N)。
  • 自动持久化:.env 中的 COMPOSE_PROFILES、OCTO_SEARCH_BACKEND、OCTO_SEARCH_PRODUCER_ON 会被脚本自动写入,确保后续 docker compose up -d 不会回退状态。

5. 回滚流程

5.1 Docker Compose 回滚

5.1.1 回滚到旧镜像版本
cd /path/to/octo-deployment/docker

# 1) 恢复 .env 和 docker-compose.yaml
cp .env.backup.YYYYMMDDHHMM .env
cp docker-compose.yaml.backup.YYYYMMDDHHMM docker-compose.yaml

# 2) 停止当前服务
docker compose down

# 3) 如果需要回滚数据库,先恢复数据(见 5.1.2)
#    注意:必须在启动新容器前恢复,否则新容器启动会再次执行迁移

# 4) 使用旧配置启动
docker compose up -d
5.1.2 数据库回滚

⚠️ 重要警告:数据库迁移不一定可逆。octo-server 的自动迁移(gorp)只记录 up 方向,通常不提供 down 迁移脚本。如果升级已执行了不可逆的 schema 变更,回滚的唯一可靠方式是恢复备份。

# 停止应用服务(保持 MySQL 运行)
docker compose stop octo-server web admin summary-api summary-worker marketplace speech speech-admin docs-backend docs-html

# 恢复 MySQL dump
docker compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -u root' \
  < "octo-mysql-backup-YYYYMMDDHHMM.sql"

# 恢复 MinIO 数据(如有必要)
docker compose stop minio
docker run --rm -v octo_minio-data:/data -v $(pwd):/backup busybox \
  sh -c "rm -rf /data/* && tar xzf /backup/minio-backup-YYYYMMDDHHMM.tar.gz -C /data"
docker compose start minio

# 重启所有服务(使用旧配置)
docker compose up -d
5.1.3 回滚前的检查清单
  • [ ] 确认旧镜像在本地或镜像仓库中仍然可用(未被清理)。
  • [ ] 确认已恢复 .env 和 docker-compose.yaml 备份。
  • [ ] 如果有数据库迁移,确认已恢复 MySQL dump。
  • [ ] 如果有 MinIO 数据结构变化,确认已恢复 MinIO 备份。
  • [ ] 如果 search 模块已开启回填,确认 OpenSearch index 是否需要重建。

5.2 Helm 回滚

# 查看 release 历史
helm history octo -n 

# 回滚到上一个版本
helm rollback octo -n 

# 回滚到指定版本号
helm rollback octo  -n 

# 验证回滚状态
helm status octo -n 
kubectl get pods -n  -w
  • 将所有 Kubernetes 资源(Deployment、Service、ConfigMap、Secret 等)恢复到指定 revision 的状态。
  • 触发滚动更新,旧版本 Pod 将重新启动。
  • 不会自动回滚数据库 schema 变更。如果 pre-upgrade hook Job 已经执行了不可逆的数据库迁移,需要手动恢复数据库。
# 先将应用副本缩为 0(避免双写)
kubectl scale deployment octo-server --replicas=0 -n 
# 等待所有 Pod 停止后,通过 port-forward 恢复备份
kubectl port-forward -n  svc/mysql 33306:3306 &
MYSQL_PWD="" mysql -h 127.0.0.1 -P 33306 -u root \
  < "octo-mysql-backup-YYYYMMDDHHMM.sql"
kill %1
# 再执行 helm rollback
helm rollback octo -n 

5.3 数据库回滚注意事项

场景 是否可逆 回滚方法
PATCH 升级,仅代码变更无 schema 变更 ✅ 可逆 回滚镜像/重启即可
MINOR 升级,新增表/列(ADD TABLE/COLUMN) ⚠️ 有条件可逆 旧版代码通常能正常运行(忽略多余列),但建议恢复备份以保持 schema 一致
MAJOR 升级,列类型变更/删除列/表重组 ❌ 不可逆 必须恢复备份
search 模块首次开启(新建 OpenSearch index) ✅ 可逆 删除 OpenSearch index + 将 OCTO_SEARCH_BACKEND 改回 disabled
docs 模块迁移(docs-migrate-entrypoint) ⚠️ 取决于具体迁移 检查 migrations/upgrades/ 目录是否有对应的 .down.sql;如无则需恢复备份
drive 模块迁移(golang-migrate) ✅ 可逆 golang-migrate 支持 down 迁移,但 Helm hook 默认只执行 up;手动执行 migrate down 需要谨慎

6. 版本兼容性

6.1 当前已知版本镜像(v0.2.0 参考)

组件 镜像 v0.2.0 Tag docker-compose 默认 Tag
octo-server octo-server v1.13.0 latest ⚠️
octo-web octo-web onprem-v1.12.1-loop-cdn latest ⚠️
octo-admin octo-admin-web v1.7.0 latest ⚠️
octo-fleet (multica-backend) octo-multica-backend prod-v0.6.0 profile fleet
octo-docs-backend octo-docs-backend 0.6.0 profile docs
octo-marketplace octo-marketplace 0.1.1 latest ⚠️
octo-smart-summary-api octo-smart-summary-api 1.8.0 latest ⚠️
octo-smart-summary-worker octo-smart-summary-worker 1.8.0 latest ⚠️
octo-speech octo-speech v1.4.1 profile speech
octo-speech-admin octo-speech-admin v1.4.1 profile speech
octo-search-indexer octo-search-indexer sha256:483b33fc... latest ⚠️
wukongim wukongim / wukongim/wukongim v2.2.5-20260422 v2.2.4-20260313(OSS)
nginx nginx 1.27-alpine nginx:1.27-alpine
MySQL mysql 8.0 mysql:8.0
Redis redis 7-alpine redis:7-alpine
MinIO minio RELEASE.2025-04-22T22-12-26Z RELEASE.2025-04-22T22-12-26Z
MinIO mc minio/mc RELEASE.2025-04-16T18-13-26Z RELEASE.2025-04-16T18-13-26Z
Kafka (search) kafka 3.8.0 profile search
OpenSearch (search) octo-search-opensearch-ik 2.17.0 profile search
PostgreSQL (fleet) postgres 15-alpine profile fleet-db

⚠️ 重要:docker-compose.yaml 中多个核心服务镜像默认使用 `:latest` tag(octo-server、octo-web、octo-admin、octo-marketplace、octo-smart-summary-api/worker、octo-search-indexer)。生产环境强烈建议在 `.env` 中通过 `OCTO_SERVER_IMAGE` 等变量固定到具体版本 tag,避免意外升级。

6.2 基础设施版本要求

组件 最低版本 推荐版本 备注
Docker Engine 待确认 24.x+ 需要 Compose V2
Docker Compose V2 V2.20+ docker compose 插件
Kubernetes 待确认 1.27+ Helm chart 要求待确认
Helm 3.10+ 3.14+
MySQL 8.0 8.0.x 镜像固定 mysql:8.0
Redis 7.x 7-alpine
MinIO RELEASE.2025-04-22 同左 镜像固定到特定 release,不建议自行升级
WuKongIM v2.2.x v2.2.5-20260422 镜像固定,升级需验证 wk.yaml 兼容性

6.3 已知 Breaking Changes

⚠️ 暂无完整官方 breaking changes 记录。以下为从源码和 release notes 中提取的已知变更:

版本 变更类型 说明 影响
v0.2.0 新增模块 新增 Loop/Fleet、Marketplace、Docs 模块 需新增数据库、环境变量、profiles
v0.2.0 配置变更 nginx 路由新增 /fleet、/summary、/market、/api/v1/docs 规则 nginx 配置必须同步更新,否则前端路由 404
v0.2.0 安全加固 新增 preflight 检查 OCTO_NOTIFY_INTERNAL_TOKEN、OCTO_WUKONGIM_MANAGER_TOKEN 旧版 .env 升级必须补充这两个变量,否则服务无法启动
v0.2.0 数据库 新增 octo_marketplace、octo_docs、octo_drive(fleet)数据库 升级时需要手动创建新增库和用户,或使用 market-preflight 等服务
v0.2.0 前端路由 octo-web v1.11.2 → v1.12.x 与 fleet prod-v0.6.0 路由前缀修复 旧版 fleet 路由会 404,必须配套升级 web 和 fleet
v0.2.0 Docker volume volume 命名从目录前缀改为 ${COMPOSE_PROJECT_NAME}_ 如果使用非默认 project name,需确认卷名映射
INCIDENT-2026-05-16 volume 隔离 修复了多克隆共享 volume 的问题 升级不影响现有数据,但后续新建克隆需注意 COMPOSE_PROJECT_NAME
待确认 WuKongIM token tokenAuthOn: true 配置和 managerToken 环境变量约定 旧版空 token 会导致 manager API 无认证访问
待确认(需查 release notes) — 跨版本 breaking changes 请查阅 GitHub Releases 建议先在测试环境验证

通用建议:由于目前官方未提供完整的跨版本 breaking changes 清单,任何版本升级都应先在测试环境完整验证,包括登录、发消息、文件上传、语音、搜索(如启用)等核心功能。

6.4 组件间版本依赖

组件 强依赖 说明
octo-web ↔ octo-server API 版本兼容 web 调用 server API,建议同版本
octo-admin ↔ octo-server API 版本兼容 admin 管理 API
octo-server ↔ wukongim Webhook/manager API server 调用 WK manager API,token 必须一致
octo-server ↔ minio SigV4 签名、bucket 策略 minio-init 预配的 bucket 和策略须匹配 server 预期
summary-api ↔ octo-server internal callback HMAC OCTO_NOTIFY_INTERNAL_TOKEN 必须一致
search-indexer ↔ Kafka ↔ octo-server Kafka topic 格式、cursor 表 search 各组件版本需配套
docs-backend ↔ octo-server notify token、MinIO bucket OCTO_DOCS_NOTIFY_TOKEN 需一致
marketplace ↔ octo-server OCTO_API_URL 认证回调

7. 各模块升级注意事项

7.1 核心服务

MySQL (`mysql:8.0`)
  • 镜像固定在 mysql:8.0(大版本),通常跟随 Docker 官方 8.0 补丁更新。
  • 升级风险:MySQL 大版本升级(如 5.7 → 8.0)风险极高,OCTO 当前不支持 MySQL 5.7。
  • 升级前:必须 mysqldump 全量备份。
  • 数据卷:mysql-data 命名卷,升级保留数据。
  • init-extra-dbs.sh 仅在首次初始化时执行,升级不会重新创建数据库/用户。
Redis (`redis:7-alpine`)
  • 无状态缓存服务,镜像升级风险低。
  • 数据卷:redis-data(AOF/RDB 持久化)。
  • 升级时重启即可,无需数据迁移。
MinIO (`RELEASE.2025-04-22T22-12-26Z`)
  • ⚠️ 镜像固定到特定 release,不建议自行升级到 :latest。mc 镜像版本必须与 server 版本同步。
  • 升级 MinIO 前需验证:
  • mc admin user add upsert 语义是否变化。
  • mc anonymous set API 是否变化。
  • MINIO_ROOT_PASSWORD 长度检查是否仍然有效。
  • 数据卷:minio-data,包含所有对象存储数据(聊天附件、头像、文件、文档附件等)。
  • 升级后 minio-init 会重新执行(幂等),会补全缺失的 bucket 和策略。
WuKongIM (`wukongim/wukongim:v2.2.x`)
  • ⚠️ 镜像固定到特定版本,不同 release 间 tokenAuthOn 和 managerToken 约定不稳定。
  • 升级前必须验证:
  • wk.yaml 中的 tokenAuthOn: true 被新版本支持。
  • WK_MANAGERTOKEN 环境变量绑定正确。
  • TCP/WS 端口和外部地址配置兼容。
  • 数据卷:wukongim-data,包含消息通道元数据(注意:消息历史存在 MySQL,不在此卷)。
  • healthcheck 依赖 managerToken,如果 token 配置错误 WuKongIM 会被标记 unhealthy。
octo-server
  • 核心 API 服务,启动时自动执行数据库迁移。
  • 重启策略:on-failure:5(而非 unless-stopped),启动依赖失败时会自动重试 5 次。
  • 升级后重点关注:
  • 迁移日志:搜索 migrate、ALTER、CREATE TABLE 等关键字确认迁移成功。
  • 配置校验:OCTO_MASTER_KEY 必须是 32 字节,server 启动时会校验。
  • 端口连通性:/v1/ping 健康检查通过。
octo-web(前端 SPA)
  • 纯静态资源,无状态,升级风险低。
  • nginx 配置 (web/default.conf.template) 必须与镜像版本匹配。新版本镜像可能需要新的路由规则。
  • 升级时必须同时更新 nginx 配置,否则会出现 SPA 路由 404、API 代理错误。
octo-admin(管理后台)
  • 纯静态资源,无状态。
  • 同样需要 nginx /admin/ 路由规则匹配。
nginx
  • 反向代理层,配置文件位于 docker/nginx/。
  • 升级 nginx 镜像通常安全,但配置文件变更必须随版本同步更新。
  • 关键配置文件:
  • nginx/nginx.conf:主配置(限流、日志、upstream)。
  • nginx/conf.d/octo.conf.template:OCTO 路由规则(/api/、/ws/、/admin/、/fleet/、/summary/、/market/、bucket 代理等)。
  • nginx/web/default.conf.template:octo-web 容器内路由。
  • 配置不匹配的典型症状:前端 API 请求 404、WebSocket 连接失败、文件下载 403/404。

7.2 speech 模块

  • Profile:COMPOSE_PROFILES=speech。
  • 组件:octo-speech(语音服务)、octo-speech-admin(管理控制台)。
  • 数据库:octo_speech,用户 speech。
  • 升级步骤:
  1. 确认 `.env` 中 `SPEECH_API_KEY`、`SPEECH_DB_PASSWORD`、`SPEECH_ADMIN_PASSWORD`、`SPEECH_ADMIN_JWT_SECRET` 已设置。
  2. `docker compose --profile speech pull`。
  3. `docker compose --profile speech up -d`。
  4. 如需 `force-recreate nginx`(因为 speech 相关 nginx 配置可能更新)。
  5. 重启 octo-server 使其重新加载 `SPEECH_API_KEY`。
  • API Key:升级不会清除 speech-admin 中已创建的应用和 API Key,无需重新创建。
  • 注意:speech-admin 默认绑定 loopback(127.0.0.1:28088),不通过 nginx 暴露。

7.3 docs 模块

  • Profile:COMPOSE_PROFILES=docs。
  • 组件:octo-docs-backend(API + 协同)、octo-docs-html(前端)、octo-docs-indexer(Tika 全文索引)。
  • 数据库:octo_docs,用户 docs。
  • 迁移入口:docs-migrate-entrypoint.sh(三阶段启动,见 4.3 节)。
  • 升级要点:
  1. docs-backend 镜像版本需 ≥ 0.3.0 才支持自动迁移。
  2. 升级前确认 `OCTO_DOCS_DB_PASSWORD`、`OCTO_DOCS_NOTIFY_TOKEN` 已在 `.env` 中设置。
  3. 首次升级到支持 docs 的版本时,需要手动创建 `octo_docs` 数据库和 `docs` 用户(`init-extra-dbs.sh` 不会在升级时执行)。
  4. MinIO bucket `octo-docs-attachments` 需要存在(`minio-init` 会自动创建)。
  5. 观察 docs-backend 日志中 `[docs-init]` 前缀的迁移输出,确认 schema.sql 导入和增量迁移成功。
docker compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -u root' <<'SQL'
CREATE DATABASE IF NOT EXISTS octo_docs CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS 'docs'@'%' IDENTIFIED BY '';
ALTER USER IF EXISTS 'docs'@'%' IDENTIFIED BY '';
GRANT ALL PRIVILEGES ON octo_docs.* TO 'docs'@'%';
FLUSH PRIVILEGES;
SQL

7.4 search 模块(高风险)

⚠️ search 模块是升级风险最高的模块,涉及 OpenSearch、Kafka、indexer 三个组件协同。

  • Profile:COMPOSE_PROFILES=search(基础设施)+ search-tools(一次性工具)。
  • 组件:search-opensearch(OpenSearch 2.17 with IK)、search-kafka(Kafka 3.8.0)、es-indexer(实时索引器)。
  • 首次开启:使用 docker/scripts/search-upgrade.sh 脚本,严格按 6 步执行并通过 5 个 Gate。
  • 升级注意事项:
  • OpenSearch 版本升级(如 2.x → 3.x)风险极高,需要索引重建。OpenSearch 2.17 → 2.x 小版本升级风险中等,建议先在测试环境验证。
  • indexer 镜像升级:注意 Kafka topic 兼容性和索引 mapping 变更。如果 mapping 变更不兼容,可能需要全量重建索引。
  • Kafka 升级:3.8.0 是当前版本,Kafka 版本间协议兼容性较好,但数据卷 kafka-data 需要妥善备份。
  • DLQ spill:search-dlq-spill 卷包含索引器死信队列溢出数据,升级时需保留。
  • Backfill checkpoint:search-backfill-state 卷包含回填断点,重建会导致从头开始。
cd /path/to/octo-deployment/docker

# 1) 拉取新镜像
docker compose --profile search --profile search-tools pull

# 2) 重启基础设施
docker compose --profile search up -d search-opensearch search-kafka es-indexer

# 3) 等待 OpenSearch 集群健康
docker compose exec search-opensearch curl -s http://localhost:9200/_cluster/health

# 4) 重启 octo-server(如果 OCTO_SEARCH_BACKEND 有变化)
docker compose up -d octo-server

# 5) 运行 gate 检查
bash scripts/search-upgrade.sh --check
# ⚠️ 这会删除并重建所有搜索索引,期间搜索功能不可用
# 1) 删除旧索引(通过 OpenSearch API)
docker compose exec search-opensearch curl -XDELETE http://localhost:9200/octo-message
# 2) 重新执行 search-upgrade.sh 的 step 4-6 回填
bash scripts/search-upgrade.sh --from 4

7.5 fleet/drive 模块

  • Profile:COMPOSE_PROFILES=fleet,fleet-db(使用内置 PostgreSQL)或 COMPOSE_PROFILES=fleet(使用外部 PG)。
  • 组件:octo-fleet(multica-backend)、fleet-postgres(内置 PostgreSQL 15)、drive(云盘服务)、drive-config(配置渲染 init 容器)。
  • 数据库:fleet 使用 PostgreSQL(fleet-postgres-data 卷),不是 MySQL。
  • 升级要点:
  • fleet 需要 PostgreSQL,是 OCTO 中唯一使用 PG 的模块。
  • drive 配置通过 drive-config init 服务渲染到 drive-config 卷,不能直接修改 YAML(因为不支持环境变量插值)。
  • Helm 环境下 drive 有专门的 pre-upgrade 迁移 Job(使用 golang-migrate),升级时会自动执行。
  • v0.2.0 修复了 octo-web v1.11.2 与 fleet prod-v0.6.0 的路由前缀不匹配问题,web 和 fleet 必须配套升级。

7.6 summary(智能摘要)模块

  • Profile:COMPOSE_PROFILES=summary。
  • 组件:summary-api、summary-worker。
  • 数据库:octo_summary(读写),主库 octo 的只读访问(summary_reader 用户)。
  • LLM 配置:升级时确认 LLM_API_URL、LLM_API_KEY、LLM_MODEL 仍然有效。
  • 升级风险低,服务内嵌自动迁移。
  • 注意 OCTO_NOTIFY_INTERNAL_TOKEN 在 summary-api、summary-worker、octo-server 三者间必须一致。

7.7 marketplace 模块

  • 组件:marketplace,无单独 profile(默认包含在核心服务中)。
  • 数据库:octo_marketplace。
  • 预配服务:market-preflight(每次启动执行,幂等)负责创建库和用户,即使升级也会运行。
  • 升级时 market-preflight 会自动确保 octo_marketplace 库和 marketplace 用户存在。
  • 注意 OCTO_MARKETPLACE_DB_PASSWORD 不能是字面默认值 marketplace(preflight 会拒绝)。

8. 升级后验证清单

8.1 基础设施验证

  • [ ] 所有容器/Pod 状态为 healthy/Running:docker compose ps / kubectl get pods
  • [ ] MySQL 可连接,所有数据库存在:octo、octo_summary、octo_speech(如启用)、octo_docs(如启用)、octo_marketplace、octo_drive(如启用)
  • [ ] Redis PING 正常
  • [ ] MinIO 健康检查通过:/minio/health/live 返回 200
  • [ ] WuKongIM 健康检查通过:/health 或 /varz(需 token)
  • [ ] nginx 健康检查通过:/_nginx_up 返回 200

8.2 核心功能验证

  • [ ] 健康检查接口:/api/v1/health 或 /v1/ping 返回 200
  • [ ] Web 前端:访问 https://:/ 正常加载登录页
  • [ ] Admin 控制台:/admin/ 可访问
  • [ ] 登录:使用管理员账号登录成功
  • [ ] 发消息:1v1 消息和群消息发送/接收正常
  • [ ] WebSocket:WS 连接正常(消息实时推送)
  • [ ] 文件上传:发送图片/文件成功,可正常下载/预览
  • [ ] 头像/群组资料:修改头像等 MinIO 相关操作正常

8.3 模块功能验证(按启用情况)

  • [ ] speech:语音输入可用,语音转文字功能正常
  • [ ] docs:文档创建、编辑、协同、附件上传正常
  • [ ] summary:智能摘要功能正常,summary-api 健康检查通过
  • [ ] marketplace:技能市场页面可访问,插件列表加载正常
  • [ ] fleet/loop:Runtime 注册正常,Workspace 创建和任务执行正常
  • [ ] drive:云盘文件上传/下载/列表正常
  • [ ] search:消息搜索返回正确结果,search-upgrade.sh --check 所有 Gate 通过

8.4 集成验证

  • [ ] OpenClaw/Octo 连接:OpenClaw Gateway 状态显示 Octo ON OK
  • [ ] octo-daemon:Runtime 注册和在线状态正常
  • [ ] 移动端/桌面端(如有):连接正常
  • [ ] 自签名证书(如使用):NODE_EXTRA_CA_CERTS 指向的证书未过期
  • [ ] HTTPS:TLS 证书有效,无证书警告

8.5 日志和监控验证

  • [ ] 无 FATAL 级错误日志:docker compose logs 2>&1 | grep -i fatal
  • [ ] 无重复的 migration 错误
  • [ ] octo-server 无数据库连接错误
  • [ ] WuKongIM 无 token 认证错误
  • [ ] MinIO 无 access denied 错误

9. 故障恢复 SOP

9.1 升级失败的通用处理流程

发现升级失败
  ↓
1. 立即停止用户流量(如需紧急止损,可临时关闭 nginx 端口)
  ↓
2. 收集诊断信息
   - docker compose ps / kubectl get pods
   - docker compose logs --tail=200 
   - kubectl describe pod  / kubectl logs  --previous
  ↓
3. 判断故障类型
   ├─ 配置错误(.env 缺变量、token 未设置)→ 修复配置,重新 up -d
   ├─ 数据库迁移失败 → 分析迁移错误,决定修复或回滚
   ├─ 镜像拉取失败 → 检查镜像仓库地址和网络
   ├─ 依赖服务未就绪 → 等待或重启依赖
   └─ 版本不兼容 → 执行回滚流程
  ↓
4. 如果 5 分钟内无法修复 → 执行回滚
  ↓
5. 回滚后验证所有功能正常
  ↓
6. 记录故障现象、根因、解决过程到运维知识库

9.2 常见故障及处理

故障 1:preflight 检查失败,服务无法启动
[preflight] FATAL: OCTO_NOTIFY_INTERNAL_TOKEN is empty — set it in .env
[preflight] FATAL: OCTO_WUKONGIM_MANAGER_TOKEN is still a CHANGE_ME / CHG_ME placeholder
# 生成新 token
echo "OCTO_NOTIFY_INTERNAL_TOKEN=$(openssl rand -hex 32)" >> docker/.env
echo "OCTO_WUKONGIM_MANAGER_TOKEN=$(openssl rand -hex 32)" >> docker/.env

# 重启
docker compose up -d
故障 2:octo-server 启动失败,提示 MASTER_KEY 错误
故障 3:数据库迁移卡住或报错
  • 数据库表被锁(长事务)。
  • 磁盘空间不足。
  • 迁移 SQL 与现有数据冲突。
# 1. 检查 MySQL 进程列表
docker compose exec mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -u root -e "SHOW PROCESSLIST;"'

# 2. 检查磁盘空间
df -h
docker system df

# 3. 如果迁移报错,记录错误日志后决定:
#    a. 修复数据问题后重启 octo-server
#    b. 回滚数据库备份 + 回滚版本
故障 4:nginx 502 Bad Gateway
# 确认 octo-server 是否 healthy
docker compose ps octo-server

# 检查 octo-server 日志
docker compose logs octo-server --tail=50

# 检查 nginx 配置是否正确(特别是升级后)
docker compose exec nginx nginx -t

# 如果 nginx 配置未更新,强制重建
docker compose up -d --force-recreate nginx
故障 5:前端页面空白或路由 404
# 确认 nginx/web/default.conf.template 是新版本
git status docker/nginx/web/default.conf.template

# 强制重建 web 和 nginx
docker compose up -d --force-recreate web nginx
故障 6:WuKongIM unhealthy,token 认证失败
# 检查 WK_MANAGERTOKEN 是否与 OCTO_WUKONGIM_MANAGER_TOKEN 一致
docker compose exec wukongim env | grep WK_MANAGERTOKEN
# 对比 .env 中的值

# 检查 wk.yaml 中 tokenAuthOn 是否为 true
docker compose exec wukongim cat /root/wukongim/wk.yaml | grep tokenAuthOn
故障 7:search 模块 Gate 检查失败
  • G1 失败(cursor 未 seed):重新运行 bash scripts/search-upgrade.sh --from 2。
  • G2 失败(producer 未开启):确认 .env 中 OCTO_SEARCH_PRODUCER_ON=true,重启 octo-server。
  • G3 失败(index 不可读或 reconcile 不通过):检查 OpenSearch 日志,可能需要重新 backfill(--from 4)。
  • G4 失败(别名未绑定):重新运行 step 5(--from 5)。
  • G5 失败(reader 未切换到 es):确认 OCTO_SEARCH_BACKEND=es,重启 octo-server。
故障 8:MinIO 403 Access Denied(图片/文件无法加载)
# 检查 minio-init 日志
docker compose logs minio-init

# 手动重新运行 minio-init
docker compose up -d --force-recreate minio-init
docker compose restart octo-server

9.3 紧急联系方式和后续处理

  1. 保留现场:不要立即清理失败的容器或日志。
  2. 收集信息:
  • docker compose ps 输出
  • docker compose logs > upgrade-failure-$(date +%Y%m%d%H%M).log
  • .env 文件(脱敏后)
  • 具体版本号(旧版本和目标版本)
  1. 回滚后在测试环境复现问题,定位根因后再安排下次升级窗口。

附录 A:快速升级命令速查

Docker Compose 小版本升级(PATCH)

# 备份
cd octo-deployment/docker
cp .env ".env.bak.$(date +%Y%m%d)"
docker compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysqldump -u root \
  --single-transaction --routines --triggers --databases octo octo_summary octo_speech octo_docs octo_marketplace' \
  > "mysql-backup-$(date +%Y%m%d).sql"

# 拉取并重启
cd .. && git pull && cd docker
docker compose pull
docker compose up -d

# 验证
docker compose ps
curl -s http://localhost:28080/v1/ping

Docker Compose 启用新模块(如 docs)

# 1. 在 .env 中添加必要变量
# OCTO_DOCS_DB_PASSWORD=
# OCTO_DOCS_NOTIFY_TOKEN=
# COMPOSE_PROFILES=docs  # 添加 docs 到已有 profiles

# 2. 创建数据库和用户(init-extra-dbs.sh 升级时不会自动执行)
docker compose exec -T mysql sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -u root' <

Helm 升级

# 备份
helm get values octo -n octo > values-backup.yaml

# 预览 + 升级
helm diff upgrade octo ./octo -n octo \
  -f values-config.yaml -f values-images.yaml -f values-secrets.yaml
helm upgrade octo ./octo -n octo \
  -f values-config.yaml -f values-images.yaml -f values-secrets.yaml \
  --timeout 10m --wait

# 回滚(如需)
helm rollback octo -n octo

附录 B:环境变量变更检查清单(v0.1.x → v0.2.x)

变量 v0.2.0 新增 说明 默认值/生成方式
OCTO_NOTIFY_INTERNAL_TOKEN ✅ internal callback HMAC openssl rand -hex 32
OCTO_WUKONGIM_MANAGER_TOKEN ✅ WuKongIM manager API token openssl rand -hex 32
OCTO_USER_API_KEY_SECRET ✅ usersecret/botfather 加密密钥 默认回退到 OCTO_MASTER_KEY
OCTO_MARKETPLACE_DB_PASSWORD ✅ marketplace 数据库密码 openssl rand -hex 16
OCTO_DOCS_DB_PASSWORD ✅ docs 数据库密码(启用 docs 时必填) openssl rand -hex 16
OCTO_DOCS_NOTIFY_TOKEN ✅ docs 通知回调 token(启用 docs 时) openssl rand -hex 32
OCTO_SEARCH_BACKEND ✅ 搜索后端开关 disabled(首次安装)/es(开启搜索后)
OCTO_SEARCH_PRODUCER_ON ✅ Kafka producer 开关 false
OCTO_SEARCH_CURSOR_HMAC ✅ 搜索分页游标 HMAC openssl rand -hex 32
DRIVE_DB_PASSWORD ✅ drive 数据库密码(启用 drive/fleet 时) openssl rand -hex 16
TS_EXTERNAL_BASEURL ✅ octo-server 对外 URL(HTTPS 部署时必填) 根据 OCTO_DOMAIN 和 OCTO_HTTP_PORT 生成

文档状态:本指南基于 octo-deployment 仓库源码分析编写(截至 2026-09-22),部分内容(如跨版本 breaking changes、部分 Helm 配置细节、drive Docker Compose 迁移机制)标记为"待确认"。建议在实际升级操作前,结合目标版本的 GitHub Release Notes 和测试环境验证结果补充完善。