前言

在使用 Docker 的过程中,我们经常需要更新容器。虽然可以通过给镜像标签添加 latest,然后手动编辑容器来拉取最新镜像并更新,但这显然不够优雅,尤其是在容器数量众多时,手动更新更是一项繁琐的工作。

之前给大家写过一键手动更新的DockerCopilot,但还是不够优雅!!!

https://hi.keba.host/archives/ugreen-DockerCopilot

今天,就给大家介绍一款 Docker 容器自动更新神器 —— Watchtower,让你的容器更新从此告别手动,迈入自动化时代!

https://github.com/containrrr/watchtower?tab=readme-ov-file

Watchtower 的主要功能特性:

  • 自动更新: 自动检测并更新运行中的 Docker 容器。

  • 邮件通知: 支持配置邮件通知,及时获知容器更新状态。(可选)

  • 定时任务: 支持自定义定时任务,灵活控制更新频率。

  • 指定容器更新: 可以指定仅更新特定的容器或忽略某些容器。

  • 自动删除旧镜像: 更新完成后,可以选择自动删除旧镜像,节省存储空间。

  • 立即检查更新: 支持发送特定信号立即触发更新检查。

使用Compose方式部署

需要需要映射Docker运行,故仅推荐大家用Compose方式进行部署

创建Compose文件夹

该容器无需任何配置文件

services:
  watchtower:
    image: containrrr/watchtower:latest
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  # 访问 Docker 守护进程
    environment:
      - 'TZ=Asia/Shanghai'  # 设置时区为上海 
    restart: unless-stopped  # 自动重启容器
    command: --schedule "0 3 * * *" --cleanup  # 每天凌晨 3 点执行更新,并删除旧镜像

在最下面提示参数配置错误,需要在文件管理器中查看Nas是否创建了这个文件夹。

即表示运行成功

Watchtower 基本使用:常用命令与参数

Watchtower 启动后,默认会每 5 分钟检查一次容器的基础镜像是否有更新。如果有更新,它会自动下载新的镜像,并重启容器。

查看 Watchtower 日志

通过查看日志,你可以了解 Watchtower 的工作情况:

日志解读

  • Watchtower 1.7.1 表示 Watchtower 的版本号为 1.7.1。

  • Using no notifications 表示当前没有配置任何通知方式。

  • Checking all containers (except explicitly disabled with label) 表示 Watchtower 将检查所有正在运行的容器,除了那些被 com.centurylinklabs.watchtower.enable=false 标签明确禁用的容器。

  • Scheduling first run: 2025-01-18 11:03:00 +0800 CST 表示 Watchtower 计划在北京时间 2025 年 1 月 18 日 11:03:00 执行第一次更新检查。

  • Note that the first check will be performed in 27 minutes, 7 seconds 表示距离第一次检查还有 27 分钟 7 秒。

更多详细参数请参考官方文档:

https://containrrr.dev/watchtower/arguments/

Watchtower 高级配置:定制你的专属更新策略

虽然通过 docker run 命令行可以快速部署和配置 Watchtower,但使用 Docker Compose 可以让部署和配置过程更加优雅和易于管理。Compose 通过一个 docker-compose.yml 配置文件来定义和管理多容器 Docker 应用程序,使得我们可以更方便地定义 Watchtower 的运行参数、定时策略、通知方式等。

以下是一个详细的 docker-compose.yml 文件配置,包含了多种常用配置,你可以根据自己的需求进行选择和修改。

services:      # 定义服务
  watchtower:  # 定义一个名为 watchtower 的服务
    image: docker.1panel.live/containrrr/watchtower:latest  # 指定使用的镜像,这里使用 containrrr/watchtower 的最新版本镜像。你也可以指定特定版本号,例如 containrrr/watchtower:1.5.3
    container_name: watchtower        # 指定容器的名称为 watchtower,方便后续管理
    volumes:      # 指定数据卷挂载
      - /var/run/docker.sock:/var/run/docker.sock  # 将 Docker 的 socket 文件挂载到容器内部,这样 watchtower 才能与 Docker 守护进程通信,从而管理其他的 Docker 容器。
    restart: unless-stopped              # 设置容器的重启策略为 "除非手动停止,否则自动重启"
    command: --schedule "0 3 * * *" --cleanup  # 设置 watchtower 运行的命令参数
                                               # --schedule "0 3 * * *":使用 Cron 表达式设置定时更新任务,这里表示每天凌晨 3 点执行更新检查。
                                               # --cleanup:表示在每次更新容器后,自动删除旧的镜像文件,以节省磁盘空间。

更新特定容器

如果你只想让 Watchtower 更新特定的容器,可以在运行 Watchtower 时指定容器名称或 ID:

services:      # 定义服务
  watchtower:  # 定义一个名为 watchtower 的服务
    image: docker.1panel.live/containrrr/watchtower:latest  # 指定使用的镜像,这里使用 containrrr/watchtower 的最新版本镜像。你也可以指定特定版本号,例如 containrrr/watchtower:1.5.3
    container_name: watchtower        # 指定容器的名称为 watchtower,方便后续管理
    volumes:      # 指定数据卷挂载
      - /var/run/docker.sock:/var/run/docker.sock  # 将 Docker 的 socket 文件挂载到容器内部,这样 watchtower 才能与 Docker 守护进程通信,从而管理其他的 Docker 容器。
    restart: unless-stopped              # 设置容器的重启策略为 "除非手动停止,否则自动重启"
    command: --schedule "0 3 * * *" --cleanup clouddrive2 onestrm # 每天凌晨3点,只更新 clouddrive2 和 onestrm 两个容器,多个容器名称之间用空格隔开

忽略特定容器

有两种方法可以忽略特定容器,避免 Watchtower 自动更新它们

方法一:在要忽略的容器的 docker-compose.yml 文件中添加 label

假设你有一个名为 clouddrive2 的容器,你不想让 Watchtower 自动更新它。你可以在 clouddrive2 服务所在的 docker-compose.yml 文件中,给 clouddrive2 服务添加一个特殊的 label

services:
  cloudnas:  # 服务名称
    image: cloudnas/clouddrive2-unstable-test  # 使用的 Docker 镜像
    container_name: clouddrive2  # 容器的名称
    labels:
      - "com.centurylinklabs.watchtower.enable=false" # 添加此标签,告诉 Watchtower 不要更新这个容器
    environment:  # 环境变量
      - TZ=Asia/Shanghai  # 设置时区为上海
      - CLOUDDRIVE_HOME=/Config  # 设置 CloudDrive 的主目录
    volumes:  # 映射的卷
      - /volume1/CD2:/CloudNAS:shared  # 将本地的 /volume1/CD2 映射到容器内的 /CloudNAS,作为挂载目录
      - /volume1/docker/AppData/CloudDrive2:/Config  # 将本地的配置目录映射到容器内的 /Config,作为配置文件目录
      - /volume1/media:/volume1/media:shared  # 将本地的 /volume1/media 映射到容器内的 /volume1/media,让容器能访问该目录下文件
      - /volume1/docker:/volume1/docker:shared  # 将本地的 /volume1/docker 映射到容器内的 /volume1/docker,让容器能访问该目录下文件
    devices:  # 设备映射
      - /dev/fuse:/dev/fuse  # 将主机的 FUSE 设备映射到容器内
    restart: unless-stopped  # 容器在停止后会自动重启,除非手动停止
    pid: "host"  # 容器使用主机的 PID 命名空间
    privileged: true  # 设为特权容器
    network_mode: "host"  # 使用主机的网络模式,容器和主机共享网络

添加了这个 label 后,Watchtower 在检查更新时就会自动忽略 clouddrive2 容器。

方法二:使用 --label-enable 参数,并在需要更新的容器中添加 label:

这种方法需要修改 Watchtower 服务的 docker-compose.yml 文件,并给所有你想让 Watchtower 自动更新的容器添加特定的 label

services:  # 服务定义
  qbittorrent:  # 服务名称
    image: linuxserver/qbittorrent:4.6.7  # 镜像来源和版本
    labels:
      - "com.centurylinklabs.watchtower.enable=true"  # 添加此标签,告诉 Watchtower 需要更新这个容器
    container_name: qbittorrent  # 容器名称
    network_mode: host  # 使用主机网络
    environment:  # 环境变量设置
      - PUID=1000  # 用户ID
      - PGID=10  # 组ID
      - TZ=Asia/Shanghai  # 时区
      - WEBUI_PORT=8080  # 网页用户界面端口
    volumes:  # 挂载卷
      - /volume1/docker/AppData/qbittorrent:/config  # 配置文件存储路径
      - /volume1/media:/media  # 媒体文件存储路径(可选)
    ports:  # 端口映射
      - 8080:8080  # 映射网页用户界面端口
    restart: unless-stopped  # 容器重启策略

在 Watchtower 的 command 部分添加了 --label-enable 参数后,Watchtower 就只会检查并更新带有 com.centurylinklabs.watchtower.enable=true 标签的容器。

其他常用参数 (可在 command 部分添加):

参数

说明

示例

--interval, -i

设置检查间隔时间(秒)。注意:这个参数和--schedule是互斥的,你只能选择其中一个

command: --interval 300 --cleanup (每 300 秒检查一次,即每 5 分钟检查一次)

--stop-timeout

设置停止容器的超时时间(秒),默认为10s。如果你的某个容器停止时间太长可以修改该参数

command: --stop-timeout 30s --cleanup (设置停止容器的超时时间为 30 秒)

--no-restart

更新后不重启容器。

command: --no-restart --cleanup

--monitor-only

只监控容器,不更新。

command: --monitor-only

--run-once

运行一次更新检查后退出,即使容器没有更新,也会退出。

command: --run-once --cleanup

方便PTer抄作业的Compose

因QB+TR有很多PT站不支持新版本,所以希望这两个容器不会自动更新。

重建容器会保持原配置,不用担心配置丢失

qbittorrent

services:  # 服务定义
  qbittorrent:  # 服务名称
    image: docker.1panel.live/linuxserver/qbittorrent:4.6.7  # 镜像来源和版本
    labels:
      - "com.centurylinklabs.watchtower.enable=false" # 添加此标签,告诉 Watchtower 不要更新这个容器
    container_name: qbittorrent  # 容器名称
    network_mode: host  # 使用主机网络
    environment:  # 环境变量设置
      - PUID=1000  # 用户ID
      - PGID=10  # 组ID
      - TZ=Asia/Shanghai  # 时区
      - WEBUI_PORT=8080  # 网页用户界面端口
      - TORRENTING_PORT=6951  # 种子传输端口
    volumes:  # 挂载卷
      - /volume1/docker/AppData/qbittorrent:/config  # 配置文件存储路径
      - /volume1/media:/media  # 媒体文件存储路径(可选)
    ports:  # 端口映射
      - 8080:8080  # 映射网页用户界面端口
    mem_limit: 4g  # 限制内存使用量为4GB
    restart: unless-stopped  # 容器重启策略

transmission

services:
  transmission:
    image: docker.1panel.live/linuxserver/transmission:latest
    labels:
      - "com.centurylinklabs.watchtower.enable=false" # 添加此标签,告诉 Watchtower 不要更新这个容器
    container_name: transmission
    network_mode: host  # 使用主机网络
    environment:
      - PUID=0
      - PGID=0
      - TZ=Asia/Shanghai # 时区
      - TRANSMISSION_WEB_HOME=/config/webui/trguing-zh # webui皮肤
      - USER=root # 用户名
      - PASS=root # 密码
    volumes:  # 持久化存储
      - /volume1/docker/AppData/transmission:/config   # 配置文件存储路径
      - /volume1/media:/media   # 下载文件存储路径
    ports:  # 端口映射
      - 9091:9091  # 映射的 Web 界面端口
      - 51413:51413  # 映射的 P2P 端口
      - 51413:51413/udp  # 映射的 P2P UDP 端口
    restart: unless-stopped  # 重启策略

Watchtower

services:
  watchtower:
    image: containrrr/watchtower:latest  # 也可以替换为支持 arm 架构的镜像,例如:containrrr/watchtower:arm64 或者使用国内加速镜像 1panel.docker.live/containrrr/watchtower:latest
    container_name: watchtower
    environment:
      - TZ=Asia/Shanghai  # 设置时区为上海
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock  # 挂载 Docker Socket,让 Watchtower 可以访问 Docker
    command: --schedule "0 3 * * *" --cleanup  # 设置每天凌晨 3 点执行更新检查,并清理旧镜像
    labels:
      - "com.centurylinklabs.watchtower.enable=false" # 默认先禁用所有容器的自动更新