找回密碼
 立即註冊
惟家LINE群QRCODE
    查看: 1|回覆: 0

    Docker 容器要不要自動更新?Watchtower 的取捨

    [複製鏈接]

    !lvup!   100%

    363

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005752
    發表於 3 天前 | 顯示全部樓層 |閱讀模式
    跑了十個容器之後,更新變成一件麻煩事。
    有人推薦 Watchtower 自動更新,但我不建議無條件開啟

    這篇講為什麼,以及比較好的做法。



    Watchtower 在做什麼

    它定期檢查你的容器用的映像檔有沒有新版,
    有的話自動拉下來、停掉舊的、用新的重建
    1. services:
    2.   watchtower:
    3.     image: containrrr/watchtower
    4.     restart: unless-stopped
    5.     volumes:
    6.       - /var/run/docker.sock:/var/run/docker.sock
    7.     environment:
    8.       - WATCHTOWER_CLEANUP=true
    9.       - WATCHTOWER_SCHEDULE=0 0 4 * * *
    10.       - TZ=Asia/Taipei
    複製代碼

    聽起來很方便。問題在哪?

    問題一:重大變更(Breaking Changes)

    智能家居的軟體更新經常有重大變更

    實際例子:


    • Zigbee2MQTT 2.0 —— 移除了 legacy API、permit_join 改到前端、
        groups.devices 不能在設定檔裡配置、child lock 從 lock 變成 switch。
        自動更新上去的話,一堆東西會壞掉而且你不知道為什麼
    • InfluxDB 1.x → 2.x —— 查詢語言完全不同
    • Frigate —— 設定檔格式在版本之間有過調整


    半夜四點自動更新,早上起來發現家裡壞了 —— 而且你還不知道是更新造成的。

    問題二:latest 標籤的不確定性

    :latest 的話,你不知道下一次拉到的是什麼版本。

    可能是小修正,也可能是跨大版本。

    問題三:回滾很麻煩

    Watchtower 預設會清掉舊映像檔(WATCHTOWER_CLEANUP=true)。

    想回到舊版的話,你要知道「舊版是哪個版本號」——
    但你沒記錄,因為是自動更新的。

    問題四:資料庫遷移不可逆

    有些服務升級時會自動遷移資料庫結構

    降版的話資料可能讀不回來。



    比較好的做法:分級處理

    等級 A:可以自動更新

    特徵:無狀態、不影響其他服務、壞了立刻看得出來


    • Grafana
    • Uptime Kuma
    • 反向代理(Caddy、NPM)
    • 監控工具


    這些自動更新的風險低。

    等級 B:半自動(通知但不更新)

    特徵:有狀態、但不是關鍵路徑


    • Frigate
    • InfluxDB
    • 備份工具


    做法:用 Watchtower 的通知模式(只提醒不更新):
    1. environment:
    2.   - WATCHTOWER_MONITOR_ONLY=true
    3.   - WATCHTOWER_NOTIFICATION_URL=generic+http://192.168.1.50:8123/api/webhook/xxx
    複製代碼

    收到通知後,你自己挑時間更新,順便看一下 release notes。

    等級 C:絕對手動

    特徵:關鍵路徑、或有重大變更的歷史


    • Home Assistant
    • Zigbee2MQTT
    • MQTT Broker


    這三個絕對不要自動更新。

    用版本標籤而不是 latest

    這是最重要的一條建議。
    1. # 壞
    2. image: koenkk/zigbee2mqtt:latest
    3. # 好
    4. image: koenkk/zigbee2mqtt:2.12.0
    複製代碼

    好處


    • 你知道現在跑的是哪個版本
    • 重建容器不會意外升級
    • 回滾只要改一行
    • compose 檔進 Git 之後,版本歷史一目了然


    代價:要自己去看有沒有新版。

    折衷方案:用次要版本標籤
    1. image: influxdb:2        # 會跟 2.x 的最新,但不會跳到 3.x
    2. image: eclipse-mosquitto:2
    3. image: grafana/grafana-oss:11
    複製代碼

    這樣可以自動拿到修正,但不會跨大版本。

    我覺得這是最好的平衡。



    我的實際更新流程

    每個月一次,挑一個晚上


    • 看 release notes —— 找 Breaking Changes 那一段
    • 備份 —— 設定檔 + 資料目錄
    • Proxmox 快照(如果在虛擬機裡)
    • 一次更新一個服務
    • 每個更新完立刻測試
    • 記錄版本號(git commit)

    1. # 更新單一服務
    2. cd /volume1/docker
    3. # 1. 先看要更新到什麼
    4. docker compose pull frigate
    5. # 2. 記下目前的版本
    6. docker inspect frigate --format '{{.Config.Image}}'
    7. # 3. 更新
    8. docker compose up -d frigate
    9. # 4. 看日誌有沒有錯
    10. docker compose logs -f --tail 100 frigate
    11. # 5. 出問題就回滾(改回舊版本號再 up -d)
    複製代碼

    自動化輔助:檢查有沒有新版

    不用 Watchtower 也能做:
    1. #!/bin/bash
    2. # /volume1/scripts/check_updates.sh
    3. cd /volume1/docker
    4. OUT=""
    5. for svc in $(docker compose config --services); do
    6.     IMAGE=$(docker compose config | grep -A5 "^  $svc:" | grep 'image:' | awk '{print $2}')
    7.     docker pull -q "$IMAGE" > /dev/null 2>&1
    8.     LOCAL=$(docker inspect "$IMAGE" --format '{{.Id}}' 2>/dev/null)
    9.     RUNNING=$(docker inspect "$svc" --format '{{.Image}}' 2>/dev/null)
    10.     if [ -n "$LOCAL" ] && [ -n "$RUNNING" ] && [ "$LOCAL" != "$RUNNING" ]; then
    11.         OUT="$OUT$svc "
    12.     fi
    13. done
    14. if [ -n "$OUT" ]; then
    15.     curl -s -X POST -H "Content-Type: application/json" \
    16.       -d "{"services":"$OUT"}" \
    17.       "http://192.168.1.50:8123/api/webhook/docker-updates-xxxx"
    18. fi
    複製代碼

    HA 接收並做成一個感測器
    1. alias: Docker 更新通知
    2. triggers:
    3.   - trigger: webhook
    4.     webhook_id: docker-updates-xxxx
    5.     local_only: true
    6. actions:
    7.   - action: input_text.set_value
    8.     target: {entity_id: input_text.docker_updates}
    9.     data:
    10.       value: "{{ trigger.json.services[:255] }}"
    11.   - action: notify.mobile_app_charles
    12.     data:
    13.       title: 有容器可以更新
    14.       message: "{{ trigger.json.services }}"
    15. mode: single
    複製代碼

    Home Assistant 本身的更新策略

    我的原則:等 x.2 或 x.3

    每個月初出 x.0,通常一兩週內會有幾個修正版
    官方的目標是每週五出一個 patch release。

    更新前一定要做的三件事


    • 看 Breaking Changes(設定 → 更新 → 點那個更新 → 發行說明)
    • 手動備份一次
    • Proxmox 快照(如果適用)


    例如 2026.9 的重大變更:UniFi Protect 需要 7.2.105 以上、
    吸塵器的 battery_level 屬性被移除、
    Z-Wave JS 的鎖具使用者與憑證管理改成只有管理員能操作。

    這三個如果剛好是你在用的,沒看就升上去會出事。

    Zigbee2MQTT 的特別提醒

    Z2M 2.0 是重大版本,升級前一定要看遷移說明。

    它在首次啟動時會自動遷移 configuration.yaml
    並把改了什麼記錄在資料目錄的 migration-1-to-2.log

    升級之後第一件事就是去看那個檔案。

    而且 2.x 移除的東西滿多的:


    • legacy API 和 legacy availability payload
    • legacy action sensors 預設關閉
    • permit_join 設定被移除,改用前端或 MQTT 請求,
        而且最長只能 254 秒(不能永久開放)
    • 群組成員不能再用 groups.devices 設定
    • child lock 變成 switch 而不是 lock
    • update_state / update_available 實體被 update 實體取代


    ---

    總結


    • 用版本標籤,不要用 latest(或至少用次要版本標籤)
    • Watchtower 只用通知模式
    • HA、Z2M、MQTT 絕對手動
    • 每個月一次,一次一個,更新完立刻測
    • compose 檔進 Git,版本歷史就是你的回滾清單


    自動更新省下的是「按按鈕的時間」,
    但可能花掉的是「半夜排查為什麼家裡壞了」的時間。


    這個交換我覺得不划算。
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-24 11:25 , Processed in 0.081620 second(s), 24 queries .

    快速回覆 返回頂部 返回列表