更新
介绍自托管实例如何获知 Warmbly 新版本、管理面板中的更新提示代表什么,以及“更新并重启”如何拉取版本、重新构建并重启服务栈。
自托管 Warmbly 会自行检查新版本,并在管理面板显示。如果更新器与服务栈一起运行,点击一个按钮即可应用更新:获取新版本,重新创建发生变化的服务,后端恢复响应后面板重新连接。正在进行的工作不会丢失:发送和同步在重启期间暂停,之后从数据库继续。
“获取”的方式取决于实例如何安装,更新器为每种方式提供模式:
| 模式 | 适用安装 | 更新内容 |
|---|---|---|
image | 通过 install.sh 安装 | 在 .env 固定新标签,执行 docker compose pull 并重建容器,不进行构建 |
compose | Git 克隆 | 执行 git pull、docker compose build,然后重建容器 |
command | 其他方式 | 执行 git pull,再运行你自己的构建和重启脚本 |
更新提示
管理面板 :5174 侧边栏底部,在环境标签旁显示版本标记。它读取正在运行的后端构建身份,因此显示的是实际部署版本,不是检出目录声称的版本。
| 标记 | 含义 |
|---|---|
v1.4.0,灰色 | 已是最新。点击查看详情和手动检查 |
Update to v1.5.0,高亮并闪动 | 配置渠道中已有更新发布 |
Update available,高亮并闪动 | 检出目录落后于其分支,适用于跟随 main 的安装 |
Updating,蓝色并旋转 | 更新任务正在运行;从任何选项卡都可通过标记跟踪 |
Restarting,蓝色并旋转 | 更新后后端正在重新启动 |
相同信息也显示在实例 > 设置与健康状态顶部;有更新时还会出现发现项 update_available,严重级别为信息,因此只列发现的页面也会提示。
在控制台中
自托管工作区的每个成员都能在控制台顶部、套餐徽章旁看到相同版本标记:当前版本为灰色;发现新发布后,显示琥珀色“Update to vX.Y.Z”,并带闪动圆点。这样无需询问服务器运行什么版本,无权更新的人也知道有更新待处理。
能否操作取决于平台管理权限,而不是工作区角色:
- 成员只看到徽章,提示框说明版本,并提示联系平台管理员。
- 当前会话没有第二因素的平台管理员看到相同徽章;点击会说明管理访问需要双因素身份验证,并链接到“设置 > 安全”。在那里启用 2FA 或添加通行密钥,再重新登录;管理面板也受同一规则限制。
- 平台管理员点击后打开更新对话框,其中有当前和可用版本、发布说明、检出目录与更新器状态、“立即检查”按钮,以及更新并重启。点击后先进入确认页面,明确说明拉取、重建、重启、发送暂停后恢复、应用迁移及选项卡重新连接,然后才执行。
更新期间,对话框显示进度条、突出当前步骤的步骤列表,以及可展开的日志。后端因重启暂时不可用时,对话框显示正在重新连接,并持续轮询;顶部版本标记变成旋转图标,因此关闭对话框仍能看到任务,刷新页面也能重新接上。新后端响应后,对话框显示结果,短暂倒计时后重新加载控制台;如果对话框已关闭,则用提示通知新版本,并刷新所有列表。
控制台通过 GET /auth/instance 获取版本,任何成员均可读取;其余信息使用下方管理端点,仅平台管理员可访问,权限规则与管理面板相同。
如何判断版本较新
有两个信号,任一出现都会点亮版本标记:
- 发布。 将
RELEASES_GITHUB_REPO在UPDATE_CHANNEL上的最新发布,与运行构建版本比较。stable只看稳定版,dev包含预发布。标记为v1.4.0-3-gabc1234的构建表示比v1.4.0标签多三个提交,会被视为新于v1.4.0、旧于v1.4.1,因此从main构建的实例不会被反复提醒安装已包含的发布。 - 提交。 更新器运行时,按
UPDATER_FETCH_INTERVAL获取远程内容,并报告检出目录落后分支多少提交。对于跟随分支的安装,落后任何数量都算更新。
没有版本信息的构建,例如未传构建参数的镜像,报告为 dev,无法与发布比较,只能使用提交差距。
版本来自二进制本身:Dockerfile 和 make up 会写入标签、提交和构建时间,使用 internal/version;CI 对公开镜像也如此,warmblyctl status 将它打印在第一行。
升级到此版本之后的版本前
新增了两项启动要求。不满足时,拉取后实例会陷入重启循环,而不是带警告启动。点击更新前应先检查两者。
AUTH_SECRET至少需要 32 个字符。 它签署每个会话令牌,较短密钥可能从实例签发的任意令牌中被离线恢复。实时服务对同一个值JWT_SECRET应用相同下限。可以用make gen-key生成,或使用任意至少 32 字符的随机字符串,并写入安装的.env。更改它会让所有人退出登录,这是预期效果,也正适合在更新时处理。- 管理员需要双因素身份验证。 所有管理路由都会拒绝未提供第二因素的会话。应在更新之前,至少让一位管理员在控制台的设置 > 安全中登记,否则管理面板无法访问,直到有人完成。控制台本身不受影响,因此更新后仍能登记,只是在那个时刻才发现不够方便。
用以下命令检查第一项:
awk -F= '/^AUTH_SECRET=/{print length($2)" characters"}' /opt/warmbly/.env更新并重启
更新器可访问且存在更新时,按钮才会出现。它需要管理员权限 manage_settings,每次点击都会生成审计行,操作为 upgrade,对象为 instance。
通过 install.sh 安装、使用镜像模式时:
- 固定发布。 将所选标签写入
WARMBLY_TAG,保存在安装的.env中,让拉取、重建和以后手动执行的每次docker compose up都解析到相同镜像。拉取失败会恢复旧标签,避免.env留在不存在的镜像版本。 - 拉取镜像。 执行
docker compose pull。 - 重启。 对除更新器自身外的所有服务执行
docker compose up -d --no-build。 - 清理。 执行
docker image prune -f,除非设置了UPDATER_PRUNE=false。 - 等待后端。 更新器轮询
/health,直到响应,最多等待六分钟。
Git 检出使用 Compose 模式时:
- 获取。 在检出目录执行
git fetch --tags --prune。 - 拉取。 位于分支时,对远程分支执行快进合并;固定在标签时,检出最新发布。有本地修改的目录会被拒绝,不会强行合并;请提交或暂存修改,或设置
UPDATER_ALLOW_DIRTY=true。 - 构建。 对每个服务执行
docker compose build,并写入版本信息。 - 重启。 对检出目录定义的全部服务,加上所有正在运行的服务,执行
docker compose up -d --no-build,排除更新器自身。Compose 只重建镜像或配置变化的容器,因此 Postgres、Redis 和 NATS 保持运行,后端启动时应用迁移。 - 清理。 执行
docker image prune -f,除非设置了UPDATER_PRUNE=false。 - 等待后端。 更新器轮询
/health,最多六分钟,并将任务标为成功或失败。
如果更新器自己的镜像变化,它会在结果已写入磁盘后最后重建自己,让新更新器能够报告已完成任务。
对话框实时显示日志。关闭后,版本标记继续跟踪;重新加载页面也会重新接上任务。后端以新构建响应时,提示会说明当前版本,并刷新全部列表。
迁移只向前应用,因此为保证现有数据安全,更新不需要通过回滚来处理。仍请阅读备份:更新前的备份通常会让你庆幸提前准备。
更新器持有 Docker socket
更新器挂载 /var/run/docker.sock,这相当于主机 root 权限。因此在克隆安装中,它位于 updater Compose 配置组后;在所有安装中,它都只接受后端持有的持有者令牌,只在 Compose 网络响应,不公开端口。后端通过管理员权限控制按钮并记录审计。如果不希望主机授予这些信任,请关闭该配置组,手动更新。
启用更新程序
通过 install.sh 安装的实例
已经配置完成。安装器会把镜像模式更新器写入生成的 Compose 文件,指向安装目录,并生成独立 UPDATER_TOKEN,后端也从 .env 读取它。无需额外设置。
如果要手动更新,在安装目录执行:
docker compose -p warmbly pull && docker compose -p warmbly up -d如果完全不想显示按钮,删除 updater 服务,即从 docker-compose.yml 移除它,并将 UPDATER_URL=none 写入 .env。
克隆仓库后使用 Docker Compose
make up 会带 updater 配置组启动服务栈,因此标准安装已经有按钮。如果直接执行 docker compose up,请在 .env 添加:
COMPOSE_PROFILES=updater服务会按主机上的原路径挂载检出目录,由 WARMBLY_REPO_DIR 指定,默认 $PWD,使 Compose 文件的相对路径在容器内以相同方式解析;并将后端的 INTERNAL_API_TOKEN 共享为 UPDATER_TOKEN。无需其他配置。
Git 以 root 写入的文件,会在每次拉取后归还检出目录所有者,因此你在主机上的 git pull 仍可正常工作。
手动更新可使用 make upgrade,即快进拉取后运行 make up。完全隐藏按钮时,用 make up UPDATER=false 启动,并将 UPDATER_URL=none 写入 .env;面板之后只报告信息。
不使用 Docker
在裸机安装中,更新器是一个 systemd 单元,拉取后运行 scripts/upgrade-bare-metal.sh。脚本以检出目录所有者身份构建本机运行的所有产物,再交给唯一的特权安装器 warmbly-install-release,由它复制产物到 /opt/warmbly,保留各前端 config.js,先重启后端,待其响应后再启动其他服务。
cd /opt/warmbly/src
go build -o out/updater ./cmd/updater && sudo install -m 0755 out/updater /opt/warmbly/bin/
sudo install -o root -g root -m 0755 deploy/systemd/warmbly-install-release.sh /usr/local/sbin/warmbly-install-release
sudo install -m 0644 deploy/systemd/warmbly-updater.service /etc/systemd/system/
printf 'UPDATER_TOKEN=%s\n' "$(grep ^INTERNAL_API_TOKEN= /etc/warmbly/warmbly.env | cut -d= -f2-)" | sudo tee /etc/warmbly/updater.env >/dev/null
sudo chmod 0600 /etc/warmbly/updater.env
sudo systemctl daemon-reload && sudo systemctl enable --now warmbly-updater单元以检出目录所有者身份运行,随附值为 deploy,请按需修改。唯一需要 root 的步骤是安装器,因此该用户只需一行精确的 sudoers 规则,不需要更大权限:
echo "deploy ALL=(root) NOPASSWD: /usr/local/sbin/warmbly-install-release" | sudo tee /etc/sudoers.d/warmbly-upgrade >/dev/null
sudo chmod 0440 /etc/sudoers.d/warmbly-upgrade安装器归 root 所有,普通用户不可写,不接受参数,只读取检出目录下的固定路径,并拒绝其中的符号链接,因此拥有检出目录不等于拥有主机。它安装的二进制始终以无特权 warmbly 用户运行。
然后在 warmbly.env 中让后端指向更新器,并重启后端:
UPDATER_URL=http://127.0.0.1:8095也可以手动运行相同脚本:scripts/upgrade-bare-metal.sh --pull。
配置
后端:
| 变量 | 作用 | 默认值 |
|---|---|---|
UPDATE_CHECK_ENABLED | 轮询 GitHub Releases,并在面板显示新版本 | true |
UPDATE_CHECK_INTERVAL | 发布检查频率,最短 5m | 30m |
UPDATE_CHANNEL | stable 跟随稳定发布,dev 也提供预发布 | stable |
RELEASES_GITHUB_REPO | 将其发布视为 Warmbly 版本的 owner/repo;分支实例可指向自己的分支 | warmbly/warmbly |
RELEASES_GITHUB_TOKEN | 可选,仅用于提高 GitHub API 速率额度 | 未设置 |
UPDATER_URL | 更新器地址;未设置或为 none 时,面板只报告信息 | Compose 下为 http://updater:8095 |
UPDATER_TOKEN | 提交给更新器的持有者令牌。应使用独立值;一条命令安装器会生成 | INTERNAL_API_TOKEN |
更新器:
| 变量 | 作用 | 默认值 |
|---|---|---|
UPDATER_TOKEN | 接受的令牌,回退到 INTERNAL_API_TOKEN;没有令牌时拒绝启动 | 未设置 |
UPDATER_MODE | image 固定发布标签并拉取;compose 重建检出目录;command 运行 UPDATER_COMMAND | compose |
UPDATER_COMMAND | command 模式中的构建和重启命令 | 未设置 |
UPDATER_REPO_DIR | 检出目录;镜像模式下为保存 Compose 文件和 .env 的安装目录 | 工作目录 |
UPDATER_REMOTE | 获取和拉取使用的 Git 远程 | origin |
UPDATER_COMPOSE_PROJECT | 启动服务栈时使用的 -p 值 | warmbly |
UPDATER_COMPOSE_PROFILES | 每次 Compose 调用附加的配置组,使更新器自身镜像也能重建 | updater |
UPDATER_BACKEND_HEALTH_URL | 重启后持续轮询直到响应 | http://backend:8080/health |
UPDATER_FETCH_INTERVAL | 获取远程并计算落后提交数的频率 | 30m |
UPDATER_PRUNE | 成功更新后执行 docker image prune -f | true |
UPDATER_ALLOW_DIRTY | 允许在检出目录存在本地修改时更新 | false |
UPDATER_STATE_DIR | 跨重启保存最近任务的位置 | /var/lib/warmbly-updater |
UPDATER_ADDR | 监听地址 | :8095 |
端点
| 端点 | 身份验证 | 返回内容 |
|---|---|---|
GET /admin/instance/update | 平台管理员,view_analytics | 运行构建、最新发布、是否可更新、更新器和任务状态;?log=1 包含任务日志 |
POST /admin/instance/update/check | 平台管理员,manage_settings | 立即执行两项检查并返回状态 |
POST /admin/instance/update/apply | 平台管理员,manage_settings | 启动更新任务并返回,可传 {"target": "latest"} 或发布标签;过程中后端会重启 |
更新器自己的 API,即 GET /status、POST /check 和 POST /update,使用持有者令牌验证,只面向后端。
检查发现的问题
两项实例健康状态检查与本页相关:
update_available,信息级:存在新版本,显示版本及应用方法。updater_unreachable,警告级:已设置UPDATER_URL,但该地址没有响应,因此按钮无法工作。请启动更新器、修正地址,或删除该变量并手动更新。
在其他主机上运行工作节点
本页针对控制平面。通过面板安装的远程工作节点保留自己的每日自更新定时器,以及节点页面上的拉取最新版本并重启操作;参见日常运维。