8.4 KiB
title, created, updated, type, namespace, tags, related
| title | created | updated | type | namespace | tags | related | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Watchtower — почему не обновляет контейнеры | 2026-09-20 | 2026-09-20 | tech | personal |
|
|
Watchtower — почему не обновляет контейнеры
Реюзабельная теория. Живой разбор на Kraken — в family/how-to/kraken-watchtower.
Главный вывод: docker ps показывает Up (healthy) — это ничего не говорит о том, что Watchtower хоть раз что-то обновил. Отсутствие обновлений не даёт ни ошибки, ни алерта. На Kraken Watchtower «работал» 2.5 месяца и не обновил ни один из 12 контейнеров.
Четыре причины (проверять в этом порядке)
1. Не задан --interval → таймер сбрасывается каждым стартом
Без флага интервал = 24ч от момента старта процесса. Любой рестарт контейнера (reboot, docker restart, обновление самого Watchtower) обнуляет отсчёт. Если контейнер рестартуют чаще раза в сутки — проверка не наступает никогда.
Признак в логе:
level=info msg="Scheduling first run: ... in 23 hours, 59 minutes, 59 seconds"
level=info msg="Waiting for running update to be finished..."
Вторая строка — процесс проснулся, увидел незавершённый апдейт и снова уснул. Признак, что цикл заклинило.
Фикс: --interval 86400 явно, либо --schedule "0 0 4 * * *" (cron-синтаксис из 6 полей), если нужен запуск в тихое время.
2. DOCKER_API_VERSION запинен на старую версию
DOCKER_API_VERSION=1.40 в environment ломает чтение метаданных образа. Симптом:
level=info msg="Found new lscr.io/linuxserver/prowlarr:latest image (3e9bd62ca90c)"
level=info msg="Unable to update container \"/prowlarr\": no available image info. Proceeding to next."
Watchtower нашёл новый образ, но не может обновиться. В новых версиях API показывается сам: using Docker API v1.54.
Фикс: убрать DOCKER_API_VERSION из environment вообще. Watchtower сам согласует версию с dockerd.
3. Образ containrrr/watchtower не развивается
Last push containrrr/watchtower — 2023-11-11 (проверено Docker Hub API). Он несовместим с современным dockerd, отсюда и no available image info — это не только про API-версию.
Фикс: активный форк nickfedor/watchtower (актуальная версия 1.22.2, теги latest, nightly, semver).
# проверить дату образа
curl -s "https://hub.docker.com/v2/repositories/containrrr/watchtower/tags?page_size=5" \
| jq -r '.results[] | "\(.name) updated=\(.last_updated)"'
# проверить поддержку своей архитектуры (например arm64 для RPi)
curl -s "https://hub.docker.com/v2/repositories/nickfedor/watchtower/tags/1.22.2" \
| jq -r '.images[] | "\(.architecture) \(.os)"'
4. --label-enable без единого label → не обновит НИЧЕГО
С флагом --label-enable Watchtower трогает только контейнеры с label
com.centurylinklabs.watchtower.enable=true. Если label нет ни у кого — сам по себе флаг делает Watchtower бесполезным.
Проверка, кто помечен:
for c in $(docker ps --format "{{.Names}}"); do
echo "$c -> $(docker inspect $c -f '{{index .Config.Labels "com.centurylinklabs.watchtower.enable"}}')"
done
⚠️ docker inspect на контейнере без label вернёт пустую строку, а не «false» — не путать с false (явное отключение).
Рабочий конфиг
services:
watchtower:
image: nickfedor/watchtower:1.22.2
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 86400 --cleanup --label-enable
# НЕ добавлять DOCKER_API_VERSION
--interval 86400— сутки, видно в логе рядом соNext scheduled run--cleanup— удалять старые образы; без него диск забивается (на Kraken 87%)--label-enable— оптин: обновляется только то, что явно помечено
Проверка (обязательна)
Up + отсутствие ошибок ≠ работа. Нужен живой прогон:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
nickfedor/watchtower:1.22.2 --run-once --monitor-only
--monitor-only обязателен, иначе --run-once реально обновит контейнеры.
Что должно быть в выводе:
level=info msg="Watchtower 1.22.2 using Docker API v1.54"
level=info msg="Found new image" container=<X> new_id=<...>
level=info msg="Update session completed" failed=0 scanned=N skipped=0 updated=0
Found new image = баг с метаданными вылечен. updated=0 в monitor-only — нормально.
⚠️ Автообновление может сломать сервис: пинить мажор версии
Тип latest + автообновление = переход на новую мажорную версию без предупреждения. Для сервисов с миграциями БД (EF Core, Prisma, любые forward-only миграции) это необратимо:
- Jellyfin на Kraken:
latestуехал 10.11.8 → 12.1, БД мигрировала вперёд, откатить схему нельзя → сервер отдавал 503,no such column: .... Детали: personal/tech/jellyfin-db-schema-mismatch.
Правило: сервисам с БД и миграциями — пиновый тег (image: jellyfin/jellyfin:12.1), НЕ latest + watchtower. Либо не давать им label, либо сначала пин.
Питфоллы диагностики
docker logs watchtower— Watchtower пишет в stdout, в отличие от Jellyfin (тот пишет в файл). Смотреть логи легко.- Таймстемпы в логе Watchtower — UTC, локальное время сервиса может быть другим.
- Единожды увиденный
Found new imageне значит, что обновление применилось — нужна следующая строка (Unable to update/Updated). - Проверять надо фактическую дату запущенного образа, а не тег:
docker inspect <container> -f '{{index .Config.Labels "org.opencontainers.image.version"}}' docker inspect <container> -f '{{index .Config.Labels "build_version"}}'
Урок
Watchtower — компонент, который молча не работает. Его нельзя «поставить и забыть»: обязательны (а) явный --interval, (б) отсутствие DOCKER_API_VERSION, (в) периодический --run-once --monitor-only как health-check, (г) осознанное решение, каким контейнерам вообще разрешено автообновление.
Связанные
- family/how-to/kraken-watchtower — живой разбор и точные команды на Kraken
- personal/tech/jellyfin-db-schema-mismatch — что ломает автообновление мажора
- personal/tech/docker-data-root-mount-race — другой дефект «контейнеры пропали»