Skip to content

Watchtower — Docker 容器自動更新

自動偵測 Docker image 更新並重啟容器的輕量守護程序,支援 Label Enable 模式精確管理受控容器與 Email 通知。

概述

Watchtower 是一個以 Docker container 形式部署的守護程序,它定期拉取已部署容器的 image digest,若發現有新版本則自動 pull 新 image 並重啟對應容器。這讓 NAS、homelab 或輕量伺服器上的 Docker 環境能免人工維護地保持更新。

Watchtower 採用 --label-enable 模式時,只有明確標記 com.centurylinklabs.watchtower.enable=true 的容器才會被管理,未標記的容器一律略過。這個機制讓你能在同一台主機上混用自動更新(一般服務)與手動控制(生產關鍵服務)的容器,不需為每個服務個別部署更新腳本。

Email 通知只在實際發生更新時才寄送,例行排程掃描無異動時不會發信,避免通知疲勞。

核心內容

部署設計考量

Watchtower 需要掛載 Docker socket(/var/run/docker.sock)才能管理其他容器。這是它通過 Docker API 列出容器、拉取 image、重啟服務的核心機制。因此 Watchtower 容器本身具有高權限,生產環境部署時應確認主機安全邊界。

排程設定使用 6 段式 Cron 格式(秒、分、時、日、月、週),與標準 5 段 Cron 不同,需特別注意。設定值 0 0 3 * * 1 表示每週一凌晨 3 點執行。

WATCHTOWER_CLEANUP=true 確保更新後舊的 image 自動刪除,避免磁碟空間被廢棄 image 持續佔用。

Label Enable 模式

啟用 --label-enable 後,受管理的條件非常明確:目標容器必須有 com.centurylinklabs.watchtower.enable=true label。這避免了 Watchtower 意外更新不想被動到的容器(例如有固定版本需求的資料庫或 API 服務)。

在目標容器的 docker-compose.yml 中加入:

yaml
labels:
  - "com.centurylinklabs.watchtower.enable=true"

新增容器時若忘記加 label,Watchtower 不會對其執行任何操作,包括更新與重啟。

Email 通知機制

Watchtower 透過環境變數注入 SMTP 連線資訊,支援常見的 SMTP relay 服務(如 smtp2go)。WATCHTOWER_NOTIFICATION_EMAIL_DELAY 設定延遲秒數,避免同批次更新多個容器時重複發送通知。

關鍵要點

  • 需掛載 /var/run/docker.sock 才能管理其他容器(高權限,注意安全邊界)
  • --label-enable 搭配 com.centurylinklabs.watchtower.enable=true label 實現精確管理
  • 排程使用 6 段式 Cron(秒 分 時 日 月 週),例:0 0 3 * * 1 = 每週一 03:00
  • WATCHTOWER_CLEANUP=true 自動刪除舊 image,防止磁碟累積
  • Email 通知只在實際觸發更新時發送,例行掃描不發信

實際應用

Watchtower 適合用於 NAS 或 homelab 的 Docker 環境:

  • 一般自架服務:Nextcloud、監控 Dashboard、小工具自動保持最新版本
  • 減少維護負擔:免手動 docker pull + docker compose up -d 的重複操作
  • 精準控制:搭配 label-enable 模式,資料庫等關鍵服務不加 label,由 CI/CD 或手動控制

生產環境建議謹慎使用,對版本敏感的服務(MariaDB、Redis 等)不加 label,避免 breaking change 導致服務中斷。

部署設定參考

以下為實際部署時使用的完整設定,供日後查詢與複製使用。

環境參數

項目
Imagenickfedor/watchtower:latest
時區Asia/Taipei
更新排程每週一 03:00(0 0 3 * * 1
通知模式Email
SMTP 伺服器mail.smtp2go.com:2525
SMTP 帳號oz.nthu.edu.tw
寄件人u9761123@oz.nthu.edu.tw
收件人silver64527@gmail.com
通知延遲5 秒

完整設定檔 / YAML

yaml
services:
  watchtower:
    image: nickfedor/watchtower:latest
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Asia/Taipei
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 0 3 * * 1
      - WATCHTOWER_LABEL_ENABLE=true
      - WATCHTOWER_NOTIFICATIONS=email
      - WATCHTOWER_NOTIFICATION_EMAIL_FROM=u9761123@oz.nthu.edu.tw
      - WATCHTOWER_NOTIFICATION_EMAIL_TO=silver64527@gmail.com
      - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.smtp2go.com
      - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=2525
      - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=oz.nthu.edu.tw
      - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=0yAMjpozV3wrmZw2
      - WATCHTOWER_NOTIFICATION_EMAIL_DELAY=5
    command: --label-enable
    restart: unless-stopped

受管容器 Label 設定

在每個想被 Watchtower 管理的容器 docker-compose.yml 中加入:

yaml
services:
  someimage:
    container_name: someimage
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

相關概念

來源