docker-updater:Watchtower 太激进了,换这个

docker-updater 更新列表界面

如果你在 NAS 上跑了一堆 Docker 容器,大概率用过或听说过 Watchtower。它会自动检查镜像更新、拉取新版本、重启容器——全自动,省心省力。

但全自动也是问题:有时候新版本有 bug,Watchtower 不管三七二十一给你更新了,服务就挂了。想让它只更新特定容器、跳过某些关键服务,配置起来挺麻烦。更别提 Watchtower 项目已经归档(archived),不再积极维护。

docker-updater 就是来解决这些痛点的。它是一个轻量级的自托管 Web UI,专门用来管理 Docker 容器更新——但核心哲学是手动审批:有新版本了会通知你,但是否更新,你自己说了算。

项目地址:https://github.com/liquidguru/docker-updater

开源协议:MIT

支持架构:amd64 + arm64(x86 服务器、树莓派、NAS 都能跑)


为什么需要手动审批更新?

Watchtower 的思路是”全自动”,但生产环境和家庭实验室其实不太一样:

  • 家庭实验室:容器多了以后,有些是核心服务(比如反向代理、数据库),有些是玩具项目。核心服务更新前你想确认一下变更日志,而不是让它自动更新。
  • 版本稳定性:有些镜像的 latest 标签并不稳定,新版本可能引入破坏性变更。手动审批可以让你先看 Release Notes 再决定。
  • 更新节奏控制:你可以给某些容器延期更新(7天、14天、30天、90天),等别人先踩坑,再决定要不要跟。

docker-updater 的设计就是围绕这些场景:它定时检查更新,但不会自动更新,而是给你一个清晰的 Web 界面,让你决定更新哪些、跳过哪些、延期哪些。


核心功能

1. 更新管理:看得清楚,控得精准

docker-updater 会定时(默认每天凌晨3点)轮询镜像仓库,对比本地镜像的 digest 和远端最新版本。它不需要拉取镜像就能判断是否有更新——通过 Docker Registry V2 的 Manifest API 发一个 HEAD 请求就够了,省带宽也省空间。

每个容器的更新状态一目了然:

  • 待更新:有新版本了,等你审批
  • 已延期:你选择了延期,可以选 7/14/30/90 天
  • 已最新:没更新,省心
  • 备份:更新后有备份保留,可以随时回滚

审批更新时,docker-updater 会自动尝试获取 GitHub Release 的变更日志,让你在更新前就知道新版本改了什么。支持自动识别 OCI 镜像标签和 GHCR 镜像,也支持手动指定变更日志来源。

2. 多主机管理:一个界面管所有

如果你有多台 Docker 主机(比如一台 NAS、一台 VPS、一台实验机),docker-updater 支持在一个界面里管理所有主机的容器。

添加远程主机有两种方式:

  • SSH:输入 IP、端口、用户名,首次连接时自动接受并保存主机密钥(TOFU 机制),不用手动 ssh-keyscan
  • TCP:如果远程 Docker 开了 TCP 端口(不推荐,安全性差),也可以直接连

多主机模式下,每个容器卡片会显示它所属的主机标识,所有更新通知按主机分组,不会乱。

3. 安全回滚:更新失败自动恢复

这是 docker-updater 最实用的功能之一。

更新前,它会自动备份旧容器,命名为 {容器名}_old。如果新容器启动失败(比如新版本镜像有 bug,或者新增了必填环境变量但你没配置),docker-updater 会自动回滚到旧版本,避免服务中断。

你还可以选择开启”备份保留”功能:更新成功后,旧容器备份保留一段时间(默认 24 小时)。如果更新后发现新版本有问题,可以一键回滚。备份容器会自动设置重启策略为 no,避免主机重启后新旧容器同时运行导致端口冲突。

如果 docker-updater 本身意外重启,它会自动扫描残留的备份容器,修复未完成的更新/回滚操作——设计得很周全。

4. 通知与日志:知道发生了什么

docker-updater 支持多种通知方式:

  • 内置 ntfy:首次运行时自动生成一个私有的 ntfy 主题,订阅后就能接收更新通知
  • Apprise 兼容渠道:可以配置 Discord、Slack、Telegram、企业微信等任意 Apprise 支持的通知渠道

除了更新通知,docker-updater 还支持接收 GitHub Webhook:把你的 GitHub 仓库配置 Webhook 指向 docker-updater,就能把 Issue、PR、Star、Release 等事件转发成推送通知——相当于一个轻量级的 GitHub 事件通知中心。

日志方面,所有更新、回滚操作的全量日志都会持久化保存,随时可以查看。每个容器还能直接查看最近 200 行 docker 日志,不用 SSH 进服务器用 docker logs 看。

5. 其他实用特性

  • Docker Compose 感知:如果容器是用 Docker Compose 管理的,更新后 docker-updater 可以选择性重启栈内其他容器,避免其他服务缓存了旧容器的 IP
  • 自更新:docker-updater 可以自动拉取新版本镜像,通过辅助容器完成自身重启,不用手动干预
  • 自动跳过本地镜像:本地构建的、没有远端仓库的镜像,会自动跳过检查,不会报假阳性

安装部署

docker-updater 部署很简单,支持 docker run 和 docker compose 两种方式。

方式一:docker run

mkdir docker-updater && cd docker-updater
mkdir -p data

docker run -d --name docker-updater --restart unless-stopped -p 9292:9090 -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd)/data:/app/data -e CHECK_TIME=03:00 -e TIMEZONE=Asia/Shanghai ghcr.io/liquidguru/docker-updater:latest

启动后访问 http://:9292 就能打开 Web 界面。

端口说明:容器内部监听 9090 端口,映射到主机 9292 是为了避免和常用的 Prometheus 9090 端口冲突,你可以根据需要改。

方式二:docker compose

保存以下内容为 docker-compose.yml

services:
  docker-updater:
    image: ghcr.io/liquidguru/docker-updater:latest
    container_name: docker-updater
    restart: unless-stopped
    ports:
      - "9292:9090"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/app/data
    environment:
      - CHECK_TIME=03:00
      - TIMEZONE=Asia/Shanghai

在同目录下创建 data 文件夹,然后执行:

docker compose up -d

环境变量说明

| 环境变量 | 默认值 | 说明 |
|———|——–|——|
| CHECK_TIME | 03:00 | 定时检查的时间,格式 HH:MM |
| TIMEZONE | Australia/Melbourne | 时区,填 tz 数据库名称,比如 Asia/Shanghai |
| NOTIFY_URL | 自动生成 | Apprise 格式的通知地址,不填则自动生成私有 ntfy 主题 |
| GITHUB_WEBHOOK_SECRET | 空 | 配置 GitHub Webhook 通知时需要填写的密钥 |
| DOCKER_HOST | unix:///var/run/docker.sock | Docker socket 地址,多主机模式也通过此变量配置远程地址 |


使用体验与技巧

第一次打开界面

首次打开 Web 界面,会看到所有容器的更新状态。界面是暗色主题,标签页分开显示:待更新、延期、备份、已最新、未检查、全部、主机、设置。

每个容器卡片上会显示:

  • 当前镜像标签和 digest 前缀
  • 是否有更新可用
  • 延期状态(如果设置了延期)
  • 操作按钮(更新、延期、查看日志等)

审批更新的流程

1. 打开”待更新”标签页,看看哪些容器有新版本
2. 点击容器卡片上的”查看变更日志”(如果有),看看新版本改了什么
3. 决定更新就点”更新”,不想更新就点”延期”或”跳过”
4. 支持批量选中多个容器,一次性更新

多主机配置

在”主机”标签页添加远程 Docker 主机:
1. 点”添加主机”
2. 选择 SSH 或 TCP 方式
3. 填写主机信息(SSH 方式需要用户名、IP、端口)
4. 测试连接,保存

添加后,所有主机的容器会出现在同一个界面里,按主机分组显示。

通知配置

如果不想用自带的 ntfy,可以配置自己的通知渠道。比如用 Discord:

NOTIFY_URL=discord://webhook_url

或者用企业微信(通过 Apprise 支持的渠道)。具体格式参考 Apprise 文档


有什么坑?

用了一段时间,有几个地方需要注意:

1. 私有仓库支持有限:目前只支持 Bearer Token 认证的私有仓库,不支持用户名密码的基础认证。如果你用私有仓库而且是用用户名密码拉的镜像,可能识别不了。

2. 不会修改 docker-compose.yml:docker-updater 只更新运行的容器,不会改本地的 docker-compose.yml。这其实是特性而非 bug,但要注意:如果你之后手动执行 docker compose up,Compose 可能会用旧的镜像标签重新创建容器(取决于你的 tag 策略)。

3. 备份保留要注意磁盘空间:开启备份保留功能后,旧容器镜像会保留一段时间。如果更新的容器很多、镜像很大,要注意磁盘空间占用。建议根据磁盘情况调整备份保留时长,或者及时手动删除不需要的备份。

4. 新版本新增环境变量不会自动检测:如果新版本镜像新增了必填环境变量,docker-updater 不会自动检测。更新失败后需要手动查看 Release 日志,补充环境变量,然后重新更新。

5. 时区要配置对TIMEZONE 环境变量要填正确的 tz 数据库名称(比如 Asia/Shanghai),不然定时检查的时间可能不对。


和 Watchtower 比,怎么选?

| 特性 | Watchtower | docker-updater |
|——|———–|—————-|
| 更新方式 | 全自动 | 手动审批 |
| Web 界面 | 无 | 有(暗色主题,很清爽) |
| 多主机管理 | 需要每个主机跑一个 Watchtower | 一个界面管所有 |
| 回滚机制 | 无 | 自动失败回滚 + 可选备份保留 |
| 通知 | 支持 | 支持(Apprise 兼容 + 内置 ntfy) |
| 维护状态 | 已归档 | 活跃维护(2026年6月仍有提交) |
| 适合场景 | 不重要的容器、玩具项目 | 生产环境、核心服务、家庭实验室 |

简单说:

  • Watchtower 适合你完全不在乎更新风险的场景,或者容器都是无状态的不重要服务
  • docker-updater 适合你想掌控更新节奏、不想服务被自动更新搞挂的场景

总结

docker-updater 解决了一个很实际的问题:Docker 容器更新需要可控,而不是全自动。它给了你一个清晰的 Web 界面,让你知道哪些容器有新版本、新版本改了什么、你要不要更新、要不要延期。

更新失败自动回滚、多主机管理、通知推送、日志查看——这些功能加在一起,让它成为一个很完整的 Docker 容器更新管理工具。尤其是相比已归档的 Watchtower,docker-updater 还在活跃维护,值得尝试。

部署很简单,一个 docker run 就能跑起来。如果你在 NAS 上跑了一堆容器,想要更可控的更新方式,docker-updater 值得一试。


部署命令再贴一遍(复制即用):

mkdir docker-updater && cd docker-updater
mkdir -p data

docker run -d --name docker-updater --restart unless-stopped -p 9292:9090 -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd)/data:/app/data -e CHECK_TIME=03:00 -e TIMEZONE=Asia/Shanghai ghcr.io/liquidguru/docker-updater:latest

访问 http://:9292 开始用。


*截图来源:docker-updater GitHub 仓库*
*项目开源协议:MIT*

docker-updater 多主机管理

docker-updater 设置

docker-updater 备份回滚

发表评论