升级、备份与回滚
单机版是整镜像升级,分布式版按机器、按服务升级;工作节点独立升级;备份数据是第三件独立的事。这一页分开讲,并给出可回滚的锚点。
应用镜像由发布方构建并推送到 ghcr.io/yiyi-product/,客户侧只负责拉取与重建容器。分布式版的外部工作节点升级走后台「节点管理」的远程升级,与 docker compose 无关。
升级前必知
安装脚本不会自动生成升级备份
升级前由你自己完成数据备份,数据备份和保留周期由你自行管理。
pull 不会更新运行中的容器
docker compose pull 只下载镜像。正在跑的容器仍然用旧镜像,必须再执行 docker compose up -d --remove-orphans --wait 才会用新镜像重建。只跑 pull 是 「升级了但没生效」最常见的原因。
不允许通过改配置切换 Edition
单机版与分布式版之间的切换不是升级,必须走授权的专用版本升级操作并完成拓扑迁移, 见单机版迁移到分布式版。只改 .env、Compose profile 或角色变量不会生效。
单机版:整镜像升级
单机版只有三个容器,应用容器里的八个服务同版本、同镜像、一起替换:
cd /opt/YiYi-media-deploy
# 1. 拉新镜像
docker compose pull
# 2. 用新镜像重建三个容器,并等待全部健康
docker compose up -d --remove-orphans --wait
docker compose ps内置节点不需要单独升级
单机版的 Storage(node-local-storage)与 Play Agent(node-local-play-agent) 随应用容器一起替换,没有独立的节点升级步骤。节点管理页也不提供「一键远程升级」。
分布式版:按机器、按服务升级
四台机器分别在自己的部署目录里执行同样的三步:
cd /opt/YiYi-media-deploy
# 1. 部署文件有更新时才需要这一步
git pull --ff-only
# 2. 拉新镜像
docker compose pull
# 3. 用新镜像重建本机服务,并等待全部健康
docker compose up -d --remove-orphans --wait
docker compose psinstall.sh 已把本机角色写进 .env 的 COMPOSE_PROFILES,所以这些命令不需要 -f、--profile 或 --env-file。
| 步骤 | 什么时候需要 | 注意 |
|---|---|---|
git pull --ff-only | compose.yaml、install.sh、.env.example、postgres-init.sql 等被跟踪文件有更新 | 手工改过这些文件时可能失败。先 git status 与 git diff 看清改动,不要用 git reset --hard 绕过 |
docker compose pull | 每次升级 | 只下载,不生效 |
docker compose up -d --remove-orphans --wait | 每次升级 | --remove-orphans 清掉当前 profile 下已不再定义的容器;--wait 会等到全部健康才返回 |
跨机升级顺序
官方文档没有规定强制顺序,按依赖关系建议:先 control(它承载数据库、注册中心与集群许可证 relay), 再 user / media,最后 edge。升级 control 期间集群授权同步会中断,建议安排在维护窗口。
分布式版的数据目录差异
| 角色 | data/ 下的内容 |
|---|---|
control | postgres/(external 模式下不创建)、redis/、config/uploads/、license/{identity,lease}/、logs/config/ |
user | license/{sync-state,lease}/、logs/user/ |
media | license/{sync-state,lease}/、logs/media/ |
edge | license/{sync-state,lease}/、logs/gateway/ |
.env、join.env、data/、backups/、config/cluster-relay.crt、config/cluster-relay.key、config/license-public.runtime.jwk、.role、.installed 都在部署仓库的 .gitignore 里,git pull 不会动它们。
也可以重跑 install.sh 升级
在已安装目录里执行 sudo ./install.sh 同样是一次完整升级:除了拉镜像与重建容器, 它还会重新同步授权公钥、重跑一遍配置预检、检查所有内部服务、内置节点与许可证状态。
分布式版升级不能顺手改角色
这台机器的角色已经记录在部署目录里。.env 里的 YIYI_DEPLOY_ROLE 与它不一致时 脚本会直接拒绝。要换角色,得用一个新目录重新克隆安装。
数据备份
日常方式:pg_dump / pg_dumpall
不要直接复制运行中的数据库目录
日常数据库备份应使用 PostgreSQL 的 pg_dump 或 pg_dumpall,不要直接复制运行中的数据库目录。 物理目录只在迁移或复制时才动,且必须先停库。
单机版在部署目录里直接备份四个库:
cd /opt/YiYi-media-deploy
set -a; . ./.env; set +a # 让当前 shell 读到 YIYI_DB_USER
mkdir -p backups
for db in yiyi_config yiyi_user yiyi_media yiyi_storage; do
docker compose exec -T postgres \
pg_dump -U "$YIYI_DB_USER" -Fc "$db" \
> "backups/${db}-$(date -u +%Y%m%d-%H%M%S).dump"
done
chmod 0600 backups/*.dump
ls -lh backups/分布式版在 control 上备份 yiyi_config、yiyi_user、yiyi_media 三个库; 用 YIYI_DB_MODE=external 时到外部 PostgreSQL 主机上做同样的操作。 yiyi_storage 由 Storage 工作节点自己的部署配置管理,按它实际所在的实例备份。
需要连角色与授权一起导出时用 pg_dumpall:
cd /opt/YiYi-media-deploy
set -a; . ./.env; set +a
docker compose exec -T postgres pg_dumpall -U "$YIYI_DB_USER" \
> "backups/all-$(date -u +%Y%m%d-%H%M%S).sql"
chmod 0600 backups/all-*.sql要备份的目录清单
| 对象 | 位置 | 说明 | 要备份吗 |
|---|---|---|---|
| 数据库 | data/postgres | 单机版四个库 / 分布式版按角色 | 用 pg_dump,不要拷目录 |
| 后台上传文件 | data/config/uploads | Logo 等上传物 | 要 |
| 部署身份 | data/license/identity | 授权代理状态目录 | 要,丢了要找发布方重新绑定 |
| 租约 | data/license/lease | 当前授权状态 | 要 |
| 同步态 | data/license/sync-state | 仅分布式 user / media / edge | 要 |
| Storage 数据 | data/storage/ | mount-data、spool、read-cache(单机版内置节点) | 要,尤其是不在云端的 spool 数据 |
| Play Agent 缓存 | data/play-agent/ | vfs-cache、image-cache(单机版内置节点) | 缓存,按恢复策略决定 |
| 配置 | .env | 含全部凭据 | 要,权限 0600 |
| 集群证书 | config/cluster-relay.crt、config/cluster-relay.key | 仅分布式 control | 要;.key 绝不可提交或公开 |
| 授权公钥 | config/license-public.runtime.jwk | install.sh 可重新同步 | 非必需 |
| 缓存 | data/redis | Redis AOF | 不必 |
| 日志 | data/logs/<service> | 各服务日志 | 按需 |
| 节点工作目录 | 分布式版各节点自己的机器 | 挂载数据、spool、读缓存 | 见分布式工作节点部署 |
缓存目录与必须保留的数据要分开
read-cache、vfs-cache、image-cache 都是可重建的缓存; spool 里可能有尚未上传完成的文件,属于必须保留的数据。 不要把两者混为一类处理。
数据库里没有节点工作目录的内容
单机版虽然只有一个 PostgreSQL 实例,但 Storage 的挂载数据、spool 与缓存是文件系统数据, 不在 data/postgres 里。只备份数据库无法恢复它们。
配置、证书与授权状态一起打包:
cd /opt/YiYi-media-deploy
tar -czf "backups/yiyi-files-$(date -u +%Y%m%d-%H%M%S).tar.gz" \
.env config data/config/uploads data/license
chmod 0600 backups/yiyi-files-*.tar.gz这个归档含全部凭据与私钥
.env 里有数据库口令、服务令牌与集群同步令牌,config/cluster-relay.key 是集群同步私钥。 归档权限设 0600,传到部署机之外的安全位置,不要放进任何仓库或共享目录。
物理目录迁移:必须先停库
迁移或复制物理数据库目录前必须停止 PostgreSQL:
cd /opt/YiYi-media-deploy
docker compose stop postgres
cat data/postgres/PG_VERSION换数据根目录(YIYI_DATA_DIR)的完整流程:
cd /opt/YiYi-media-deploy
# 1. 停掉全部服务
docker compose stop
# 2. 整体搬到新位置(保留权限、属主与硬链接)
rsync -aHAX --info=progress2 data/ /var/lib/yiyi/
# 3. 编辑 .env,设置 YIYI_DATA_DIR=/var/lib/yiyi
# 4. 重跑安装脚本,它会在新路径重建目录、修权限与属主,然后拉起服务
sudo ./install.sh恢复
cd /opt/YiYi-media-deploy
set -a; . ./.env; set +a
# 恢复单个库
docker compose exec -T postgres \
pg_restore -U "$YIYI_DB_USER" -d yiyi_media --clean --if-exists \
< backups/yiyi_media-<时间戳>.dump恢复是覆盖操作
--clean --if-exists 会先删除目标库里已存在的对象再重建。恢复到错误的库、 或用旧转储覆盖新数据,都会造成不可逆的数据丢失。执行前确认库名与转储时间。
工作节点升级(仅分布式版)
单机版没有这一节
单机版的两个内置节点随主应用整镜像升级。下面的远程升级、卸载与版本检测只属于分布式版。
节点不由部署包安装,升级也不走 docker compose:后台「节点管理」→ 选中节点 → 「检测版本」或「一键远程升级」。控制面先查节点的部署方式,再下发匹配的升级命令。
三层安全网:
| 机制 | 做什么 |
|---|---|
| 升级前自动备份旧版本 | 把当前二进制复制成 .prev(Docker 形态还会先提取旧容器配置) |
| 30 秒健康检查轮询 | 重启后持续探测节点健康端点,最多等 30 秒 |
| 失败自动回滚旧版本 | 健康检查超时或进程起不来时,恢复 .prev 并重启 |
# 手动升级(命令由控制面生成,令牌与节点 ID 已注入)
curl -fsSL http://<config地址>:18085/api/config/nodes/install/<节点令牌>/upgrade-binary | bash
curl -fsSL http://<config地址>:18085/api/config/nodes/install/<节点令牌>/upgrade-docker | bash升级 config 之后还要升级节点
分布式版的节点二进制内置在 config 镜像里。控制面升级到新版本后, 已安装的节点不会自动更新,要在「节点管理」里对节点再做一次远程升级。
回滚思路
| 层级 | 回滚方式 |
|---|---|
| 部署文件 | git log --oneline 找到上一个提交,git checkout <提交号> -- compose.yaml install.sh,再 docker compose up -d --remove-orphans --wait。这会让下一次 git pull --ff-only 失败,处理完要恢复被跟踪文件 |
| 应用镜像 | 要回到旧版本,把对应服务的标签改成发布方提供的具体版本标签,再 pull + up -d --remove-orphans --wait |
| 数据库结构 | 表结构迁移只向前推进,没有自动降级。回到旧镜像前,先用升级前的 pg_dump 恢复数据库 |
| 配置 | .env 每次改前留一份带日期的副本,同样设 0600 |
| 节点(分布式版) | 升级脚本已自动回滚;若备份已删,重新执行旧版本的安装命令 |
| Edition / 部署模式 | 不可原地回滚。单机版升级为分布式版后不支持自动降级,见单机版迁移到分布式版 |
# 例:把应用镜像钉回一个具体版本标签
# 1. 编辑 compose 文件里对应的 image: 行,把 :latest 换成 <发布方提供的版本标签>
# 2. 生效
cd /opt/YiYi-media-deploy
docker compose pull
docker compose up -d --remove-orphans --wait
docker compose ps
# 3. 改配置前留一份 .env 副本
cp .env ".env.$(date -u +%Y%m%d)" && chmod 0600 ".env.$(date -u +%Y%m%d)"镜像与数据库要一起回滚
新版本镜像可能已经推进过表结构,数据库比旧镜像新。只把镜像换回旧标签而不恢复数据库, 旧代码可能读不懂新表结构。回滚前一定先恢复升级前的转储。
验证
升级完成后确认:
cd /opt/YiYi-media-deploy
docker compose ps # 单机版恰好三个服务;全部 Up / healthy
docker compose images # 镜像标签是本次预期的版本
curl -fsSI http://127.0.0.1:18080/ | head -1
curl -fsS http://127.0.0.1:18085/api/license/status单机版再确认两个内置节点仍在线(后台「节点管理」),以及 /api/config/deployment/capabilities 返回的 edition 与 deploymentMode 仍然匹配。
常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
docker compose pull 之后版本没变 | 没有重建容器 | 必须再执行 docker compose up -d --remove-orphans --wait |
git pull --ff-only 失败 | 本地改过被跟踪文件,或不是快进关系 | git status 与 git diff 看清改动,不要用 git reset --hard 绕过 |
单机版 docker compose ps 多于三个服务 | 混入了分布式分支的部署文件 | 单机版只应运行 yiyi-app、postgres、redis 三个服务 |
升级后 postgres 没起来 | YIYI_POSTGRES_REPLICAS 是 0 | external 模式本来就不启动内置 PostgreSQL,属正常 |
| 升级后节点仍下载旧二进制 | 仅分布式版:节点二进制在 config 镜像内,config 没升级 | 先升级 config,再对节点做远程升级 |
| 升级后所有接口 403 | 授权状态掉出 ACTIVE / GRACE | 查 /api/license/status 的 state 与 code |
pg_dump 报口令认证失败或用户名为空 | 当前 shell 没读到 .env | 先 set -a; . ./.env; set +a |
up --wait 超时 | 某个服务健康检查一直不过 | docker compose ps 定位,再 docker compose logs --tail=100 <服务> |
不要一把梭重启整机
生产主机上往往还跑着别的业务。操作范围限定在本项目的部署目录与 Compose 项目内, 不要用 docker restart $(docker ps -q)、docker system prune 这类影响全部容器的命令, 也不要重启宿主级的 docker 服务。