Watchtower 是运维 Docker 容器时最省心的自动更新工具:它能定时轮询镜像仓库,一旦发现你运行的镜像有了新版本,就自动拉取、停止旧容器、用完全相同的启动参数拉起新容器,全程无需人工干预。对于个人服务器、家庭 NAS 或边缘节点上那几十个常驻容器来说,这意味着安全补丁和 bug 修复能在发布当天就被应用,而不是在“哪天有空了再手动 docker compose pull”的拖延里慢慢过期。
一、为什么需要 Watchtower
没有自动更新时,一次典型的升级流程是:登录服务器 → docker compose pull → docker compose up -d → 祈祷配置没变 → 检查日志。容器一多,这套动作就会被无限推迟。更危险的是,镜像里的底层基础镜像(如 nginx:alpine、python:3.12-slim)常年不更新,CVE 补丁永远停在半年前。Watchtower 把“拉取 + 重建 + 重启”变成后台静默动作,把人的注意力留给真正需要判断的版本升级。
二、五分钟跑起来:最小 docker-compose
最干净的部署方式,是让 Watchtower 单独作为一个容器,去监控其它容器。下面这份 compose 文件让 Watchtower 每 30 秒检查一次更新,并在更新后清理掉旧镜像:
version: "3.8"
services:
watchtower:
image: containrrr/watchtower:latest
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Shanghai
- WATCHTOWER_POLL_INTERVAL=30
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_REMOVE_VOLUMES=false
- WATCHTOWER_INCLUDE_STOPPED=false
command: --interval 30 --cleanup
关键点只有两个:挂载 /var/run/docker.sock 让 Watchtower 拥有控制 Docker 守护进程的权限;以及把更新节奏交给 --interval(秒)。把这份文件放进你已有的 Docker 容器编排体系 里统一管理即可。
三、它到底是怎么更新的
理解原理能帮你避开大部分“明明有新版本却没更新”的误解:
- 轮询 registry:按 interval 向镜像仓库发起 manifest 请求,而不是看本地 tag。
- 比对 digest:比较远程镜像的 SHA256 digest 与当前运行容器的 digest,跟 tag 字符串无关。这是为什么
:latest也能被识别。 - 拉取新镜像:digest 不同则
docker pull新层。 - 优雅重建:发送停止信号给旧容器,再用原容器的启动命令、环境变量、挂载、网络参数原样创建新容器。
正因为“按原参数重建”,Watchtower 不会帮你改配置——它只换镜像,不动你的 docker run 参数。配置变更仍需你自己改 compose。
四、只盯你想要的容器:标签与排除
默认情况下 Watchtower 会接管宿主机上所有容器,这在生产环境往往太激进。用标签精细控制更稳妥:
# 让某个容器被监控
labels:
- "com.centurylinklabs.watchtower.enable=true"
# 让某个容器永不被自动更新(如数据库)
labels:
- "com.centurylinklabs.watchtower.enable=false"
启动时加 --label-enable,Watchtower 就只处理显式打开标签的容器;数据库、有状态中间件这类“动了就出事”的服务,建议一律打上 enable=false。下面这张表总结了常用开关:
| 环境变量 / 参数 | 作用 | 推荐值 |
|---|---|---|
| WATCHTOWER_POLL_INTERVAL | 轮询间隔(秒) | 30–300 |
| WATCHTOWER_CLEANUP | 更新后删除旧镜像 | true |
| WATCHTOWER_INCLUDE_STOPPED | 是否更新已停止容器 | false |
| WATCHTOWER_ROLLING_RESTART | 逐个滚动重启 | 多副本时 true |
| WATCHTOWER_MONITOR_ONLY | 只报告不更新 | 先用 true 观察 |
五、别静默更新:接上通知
自动更新最怕“悄悄变了但没人知道”。Watchtower 支持钉钉、飞书、Slack、邮件、Webhook 等多种通知。用 Webhook 最灵活,可以推到你自己的告警总线:
environment:
- WATCHTOWER_NOTIFICATIONS=shoutrrr
- WATCHTOWER_NOTIFICATION_URL=generic://hooks.example.com/watchtower?title=Watchtower
新手建议先把 WATCHTOWER_MONITOR_ONLY=true 打开跑一两天,确认哪些容器会被更新、通知能不能收到,再切回真正自动更新,避免一觉醒来服务被某个不兼容的新版本打挂。
六、和 CI/CD、反向代理怎么配合
Watchtower 解决的是“拉取并重建”,不是“构建”。镜像该由 GitHub Actions 这类 CI 流水线 在 push 时构建并推送到仓库,Watchtower 只负责把新镜像落到生产。二者职责清晰:CI 产出,Watchtower 消费。
对于跑在 Watchtower 后面的 Web 服务,前面通常有 Nginx 反向代理。更新瞬间旧容器停止、新容器启动,会有几百毫秒的空窗,Nginx 的 upstream 健康检查会临时摘除节点,一般用户无感知。若你的服务对零中断极其敏感,应改用 blue-green 或滚动发布方案,而非依赖 Watchtower 的硬重启。
七、安全与权限:最小暴露面
Watchtower 挂着 Docker socket,等于拿到了宿主机的 root 等价权限,必须保护好。把它放进只对内网开放的网段,并用 fail2ban 自动封禁暴破 守住 SSH 与面板入口;编辑配置时习惯用 VS Code 远程开发 走加密通道,避免明文把 socket 暴露出去。私有仓库记得挂上 registry 认证:
environment:
- WATCHTOWER_REPO_USER=youruser
- WATCHTOWER_REPO_PASS=yourtoken
# 或用 Docker config / 文件挂载更安全地注入
八、常见坑与排查清单
- digest 没变就不更新:有些镜像构建时没打内容哈希,或你用的 tag 指向了不可变构建,需确认远程确实推送了新 digest。
- 私有仓库 401:漏配
REPO_USER/REPO_PASS,或用了需要docker login的私有 registry,可挂载~/.docker/config.json。 - 更新后端口冲突:旧容器没被彻底删掉,检查是否设了
REMOVE_VOLUMES或容器名冲突。 - 资源占用高:interval 设太小会频繁请求 registry,生产建议 ≥60 秒。
九、落地清单
- 用
--label-enable只监控无状态服务,数据库打enable=false。 - 先开
MONITOR_ONLY=true观察 1–2 天,确认更新范围与通知正常。 - 配置钉钉/飞书/Webhook 通知,更新留痕。
- 开启
CLEANUP清理旧镜像,避免磁盘被旧层占满。 - 缩小 Docker socket 暴露面,配合 fail2ban 与内网隔离。
十、更新翻车了怎么回滚
自动更新最大的顾虑是“新版本有 bug 怎么办”。因为没有版本号概念,Watchtower 只认 digest,所以回滚要靠你自己在仓库里保留一个可锚定的旧版本。最稳妥的做法是给关键服务同时打一个带日期或 commit 的固定 tag,出问题立刻切回:
# 出事前先给当前镜像打一个保险标签
docker tag myapp:latest myapp:rollback-20261022
docker push myapp:rollback-20261022
# 翻车后,把 compose 里 image 改回保险标签再 up
docker compose up -d
更省心的做法是直接用 digest 锁定:把 image: myapp@sha256:<旧digest> 写进 compose,这样无论 Watchtower 怎么拉新,这个服务都钉在已知良好的版本上,等你在预发环境验证完新版本再放开。
十一、三种更新策略怎么选
Watchtower 只是众多更新方式里最轻量的一种。不同成熟度的基础设施,适合不同策略:
| 策略 | 适用场景 | 优点 | 风险 |
|---|---|---|---|
| Watchtower 自动拉取 | 个人/边缘节点、无状态服务 | 零运维、即时打补丁 | 无版本门禁、可能拉到坏版本 |
| CI 构建 + 手动部署 | 中小团队、可控发布 | 每次发布有记录可回滚 | 依赖人工、易拖延 |
| K8s 滚动更新 | 生产集群、多副本 | 零中断、健康检查护航 | 基础设施重、学习成本高 |
经验法则是:能接受几分钟空窗的无状态服务,放心交给 Watchtower;有状态、强一致或面向公网的核心链路,老老实实走带审批的发布流程。把二者分层,既享受自动化的省心,又不承担“半夜被坏镜像打挂”的代价。
Watchtower 不是银弹,它最适合“希望容器永远跑在最新稳定镜像上”的常驻服务场景。把它和 CI 构建、反向代理、安全加固编排在一起,你就能用极低的维护成本,让一整屋容器始终保持新鲜。




