Контроль версій Docker контейнерів WUD



Як перетворити хаотичне оновлення десятків Docker-контейнерів на впорядкований процес? У цій статті я розберу встановлення та детальне налаштування What’s Up Docker (WUD) на Raspberry Pi 5. Від вирішення помилок авторизації та лімітів Docker Hub до тонкого налаштування регулярних виразів для тегів і сповіщень на пошту. Гід для тих, хто прагне повного контролю над безпекою свого сервера без ризикованої автоматизації.

Вступ

Навіщо моніторити версії Docker-контейнерів? Коли у вас один або два контейнери, стежити за ними нескладно. Але коли домашній сервер перетворюється на справжній “дата-центр” (у моєму випадку – це поштовий сервер, Zabbix, WordPress, бази даних та купа допоміжних сервісів), ручна перевірка стає вкрай ресурсоємною.

Чому важливо знати про нові версії?

  • Безпека: Більшість оновлень закривають критичні вразливості.
  • Стабільність: Виправлення багів, які можуть оптимізувати роботу сервісів на моїй Raspberry Pi.
  • Функціонал: Нові фішки (як-от перехід Zabbix на нову мажорну версію).

Але є нюанс: автоматичне оновлення – це ризик. Один “дропнутий” імедж або конфлікт версій бази даних може покласти весь сервіс. Тому потрібен інструмент, який бачить усе, але не чіпає нічого без дозволу.

WUD (What’s Up Docker)

WUD – це легкий та елегантний інструмент для моніторингу версій контейнерів.

На відміну від агресивних інструментів, що намагаються оновити все і відразу, WUD сповідує філософію здорового глузду та повного контролю. Його головна задача – бути очима в репозиторіях Docker. Він автоматично сканує всі запущені контейнери, порівнює їхні версії з офіційними реєстрами та видає зрозумілий вердикт у гарному веб-інтерфейсі.

Користувач отримує не просто сухий список, а наочну панель, де одразу видно, який з сервісів застряг у минулому, а який вже готовий до апгрейду. Одна із переваг у тому, що він неймовірно легкий (що критично для Raspberry Pi) і підтримує величезну кількість способів оповіщення. Це ідеальне рішення для тих, хто хоче тримати руку на пульсі оновлень, але не готовий довіряти автоматиці долю своїх баз даних чи складних поштових конфігурацій.

Запуск WUD

Встановлення займає лічені хвилини. Оскільки я працюю на Raspberry Pi 5, для мене важливо, щоб сервіс був легким. Запуск буде відбуватися через docker-compose файл із наступним базовим вмістом:

services:
  whatsupdocker:
    image: getwud/wud
    container_name: wud
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 3000:3000
  restart: unless-stopped

Результат буде такий:

docker compose up -d
[+] up 16/16
 ✔ Image getwud/wud    Pulled                                                                                                                                           
 ✔ Network wud_default Created                                                                                                                                          
 ✔ Container wud       Created

Тепер необхідно перевірити чи контейнер запущено:

docker compose ps
NAME      IMAGE        COMMAND                  SERVICE         CREATED              STATUS                        PORTS
wud       getwud/wud   "/usr/bin/entrypoint…"   whatsupdocker   About a minute ago   Up About a minute (healthy)   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp

Авторизація на DockerHUB

Під час написання статті я зіткнувся із певними помилками, одна з яких була – Request failed with status code 429 це той випадок, коли WUD надсилає багато запитів без авторизації

Щоб позбутися цієї помилки, достатньо авторизуватись на Docker HUB із своїм логіном та паролем, а в docker-compose файл дописати дві змінні оточення:

environment:
  - WUD_REGISTRY_HUB_PUBLIC_LOGIN=username
  - WUD_REGISTRY_HUB_PUBLIC_PASSWORD=password

Після перезапуску контейнера відбудеться авторизація, і помилка зникне.

Дашборд

Після запуску в браузері необхідно перейти за посиланням: http://<IP_сервера>:3000 На головному екрнаі з’явиться список усіх контейнерів. WUD автоматично звірить версії локальних образів із тими, що доступні в мережі.

Після першого запуску я бачу мінімалістичний та інформативний дашборд. Він не перевантажений зайвими графіками, а одразу дає відповіді на головні питання. На моєму Raspberry Pi картина наступна:

12 Containers (8 updates available): Це головний показник. WUD просканував моє середовище і виявив 12 запущених контейнерів. Як бачимо, для 8 із них уже доступні оновлення. Це саме той момент, коли розумієш: якби не цей інструмент, я б навряд чи дізнався про необхідність апдейтів для більшої частини свого стека так швидко.

0 Triggers: Наразі тут нуль, оскільки я згодом додам тригер.

1 Watchers: Це внутрішній механізм WUD, який відповідає за сам процес сканування локального Docker-демона.

6 Registries: Інструмент автоматично визначив, що мої образи походять із 6 різних джерел (репозиторіїв). Це зручно, якщо ви використовуєте не лише Docker Hub, а й, наприклад, GitHub чи приватні реєстри.

Порівняння версій

Після першого аналізу я зіткнувся з наступними особливостями порівняння про які напишу детально

Оновлення одразу на мажорну версію. В мене встановвлено контейнер з БД mysql версії image: mysql:8.4 проте WUD пропонує одразу оновлення на версію mysql:9.6 що є мажорною версією і при необдуманому оновленні може призвести до проблем сумісності. Краще такі оновлення уникати, оптимізувавши процес оновлення до останньої мінорної версії.

Оновлення по дайджесту. На прикладі оновлення Zabbix де імедж має такий запис image: zabbix/zabbix-server-mysql:ubuntu-7.4-latest пропонується оновлення, проте не вказується яка наразі остання версія latest.

Специфічні оновлення. На прикладі unifi-network-application яке має наступний запис image: lscr.io/linuxserver/unifi-network-application:arm64v8-10.0.160 таким чином, WUD не може визначити наступну версію для складного тегу по типу arm64v8-10.0.160.

Для вирішення цих непорозумінь, необхідно для кожного контейнера змінювати тег під універсальний, або в лейлб додавати регулярні вирази, які б уніфікували визначення версії для подальшого порівняння.

Налаштування сповіщень

За сповіщення відповідають тригери, які відповідно до методу сповіщення необхідно налаштувати. За замовчанням тригери не встановленні, тому на головному ерані буде порожньо, при тому що створення тригерів відбувається на бекенді.

Згідно документації, визначені наступні змінні оточення, які необхідно додати в docker-compose файл WUD. Попередньо я створив емейл в своєму поштовому сервері.

- WUD_TRIGGER_SMTP_OSTRICH-MAIL_HOST=mail.ostrich.kyiv.ua
- WUD_TRIGGER_SMTP_OSTRICH-MAIL_PORT=465
- [email protected]
- WUD_TRIGGER_SMTP_OSTRICH-MAIL_PASS=mysecretpass
- [email protected]
- WUD_TRIGGER_SMTP_OSTRICH-MAIL_FROM_NAME=Whats Up Docker
- [email protected]
- WUD_TRIGGER_SMTP_OSTRICH-MAIL_TLS_ENABLED=true

Перезавантаживши контейнер, відповідний запис зявився в розділі тригерів. Також в самому тригері є кнопка тесту. Оскільки я миттєво отримав лист, то тригер працює коректно, і додаткової перевірки непотрібно.

Я сподіваюся, що шаблон листа можна змінити, щоб дані не писалися в один рядок, проте наразі цього достьатньо.

Таким чином, можна переходити безпосередньо до оновлення контейнерів.

Оновлення контейнерів

Почну із найпростіших варіантів із тегом latest. В такому випадку достатньо перед перезавантаженням завантажити свіжу версію контейнеру, і новий екземпляр вже буде запущено із новою версією.

Для оновлення необхідно виконати дві команди у відповідній робочій директорії.

docker compose pull redis
[+] pull
 ✔ Image redis:alpine           Pulled

І потім запустити цей контейнер

docker compose up redis -d
[+] up 1/1
 ✔ Container ostrich_redis Recreated

Також можна перевірити нову версію на прикладі redis контейнера:

docker exec ostrich_redis redis-server -v
Redis server v=8.6.0 sha=00000000:1 malloc=jemalloc-5.3.0 bits=64 build=c3670bd9c9f57a33

Як результат оновити список контейнерів в WUD. Навпроти редіс контейнера буде напис: No update available. В цілому можна так оновлювати інші контейнери із тегом latest.

Таке оновлення не буде означати, що WUD їх визначить за останні версії, через те, що він може порівнювати останню поточну версію із мажорною версією, що буде невірно з точки зору оновлення.

Оновлення в межах мінорних версій

Необхідно бути обережним дивлячись на мажорні оновлення, вони зазвичай відображаються червоним кльором та мають знак оклику. Оскільки Такі оновлення неприпустимі, необхідно обмежити перевірку в рамках лише поточної мажорної версії, в моєму випадку це версія 8.4.

Необхідно в docker-compose файл, в блок визначення бази даних, додати лейбл який буде обмежувати версії в рамках мінорних версій через регулярний вираз:

labels:
  - wud.tag.include=^8\.[0-9]+\.[0-9]+$

Оскільки наразі встановлення остання версія MySQL 8.4.8 то після застосування змін, запис зникне із списку оновлень. Я пропишу цей запис до всіх своїх контейнерів де використовується ця база даних.

Визначення та виправлення помилок

Відсутність попереджень через веб інтерфейс не означає, що таких зауважень чи помилок нема, вони можуть бути, проте через веб іннтерфейс необхідно переглядати на наявність помилок кожен запис, що зводить моніторинг на нівець.

Для цього краще скористатися файлом логування контейнера WUD

docker logs -f wud

Буде відображена базова інформація налаштувань і застереження, які треба буде виправити:

14:57:19.520  WARN whats-up-docker: local_unifi - No Registry Provider found
14:57:19.605  WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_unifi)
14:57:20.303  WARN whats-up-docker/watcher.docker.local: Error when processing (Request failed with status code 401) (container=local_ostrich_wp)
14:57:22.076  WARN whats-up-docker/watcher.docker.local: Error when processing (Unexpected error; no manifest found) (container=local_unifi-db)
14:57:26.965  INFO whats-up-docker/watcher.docker.local: Cron finished (12 containers watched, 3 errors, 3 available updates)

Я розберу кожну помилку індивідуально та позбудуся її

local_unifi – No Registry Provider found

Контейнер unifi-controller розміщено не на Docker Hub, а на linuxserver, тому лог і показує, що для контейнера local_unifi провайдер не визначений. По принципу попередньої рекомендації, необхідно пройти реєстрацію на сервері GitHub та створити токен, який потім буде доступний при авторизації на сервері LSCR (LinuxServer Container Registry).

Ці дані необхідно додати в WUD docker-compose.yml

environment:
...
  - WUD_REGISTRY_LSCR_PRIVATE_USERNAME=username
  - WUD_REGISTRY_LSCR_PRIVATE_TOKEN=token
...

Після перезавантаження контейнера ми позбулися наступних застережень:

  • WARN whats-up-docker: local_unifi – No Registry Provider found
  • WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_unifi)

Request failed with status code 401

Якщо ваш сервіс збирається локально з Dockerfile (наприклад, ви додаєте модуль Redis до WordPress), стандартний моніторинг не спрацює. Ви будете отримувати помилки 401 або 404.

Єдиного правильного рішення я не знайшов тому тимчасово поставлю кастомний контейнер в ігнорування, додавши наступний лейбл.

labels:
  - wud.watch=false

Unexpected error; no manifest found

Це специфічна помилка, яка виникає, коли WUD знаходить образ, але не може отримати його маніфест для архітектури arm64v8. Оскільки на Raspberry Pi 5 (arm64), це класична проблема з образами, які не мають чіткої підтримки мультиархітектурності.

В оригінальному docker-compose файлі я використав образ без вказівки архітектури:

image: mongo:8.0

Щоб позбутися помилки я замінив назву іміджа на явний вказівник із архітектурою

image: arm64v8/mongo:8.0

Висновки

Баланс між контролем та автоматизацією: WUD довів, що моніторинг може бути інформативним, не будучи агресивним. Це ідеальний “асистент”, який підказує, де потрібна увага, але залишає фінальне рішення за адміністратором.

Специфіка ARM-архітектури: Робота на Raspberry Pi 5 вимагає уваги до маніфестів та тегів. Використання явних вказівників архітектури (як у випадку з arm64v8/mongo) – запорука відсутності помилок у логах.

Гнучкість через лейбли: Система лейблів у Docker дозволяє перетворити WUD на інтелектуальний інструмент. Використання регулярних виразів для ігнорування мажорних версій (наприклад, для MySQL) рятує базу даних від потенційного краху.

Чистота логів — запорука стабільності: Налаштування провайдерів (Docker Hub, LSCR) та правильна обробка локальних збірок WordPress дозволили прибрати всі WARN-статуси, перетворивши моніторинг на надійне джерело істини.