Как Watchtower сломал мне сервис в три часа ночи
Долгое время у меня в стеке крутился Watchtower — штука, которая сама следит за обновлениями образов и тихо подтягивает новые версии. Идея красивая: ты ничего не делаешь, а контейнеры всегда свежие. На практике эта красота однажды разбудила меня в три часа ночи уведомлением «сервис недоступен».
Что произошло. У одного из контейнеров вышел новый тег latest, и это была мажорная версия — со сменой формата конфига и схемы базы. Watchtower честно сделал свою работу: выкачал новый образ, снёс старый контейнер, поднял новый. Новый стартанул, увидел старый конфиг, не понял его и упал. И так по кругу — рестарт, падение, рестарт. К утру лог был размером с небольшую книгу.
Сам виноват, конечно. latest — это не версия, это лотерея. Ты подписываешься на «что разработчик зальёт следующим», а он может залить что угодно.
После этого Watchtower я выключил. Совсем:
docker compose -f /app/watchtower/docker-compose.yml down
Теперь обновляюсь руками и осознанно. Во-первых, везде прибил конкретные теги вместо latest:
services:
paperless:
# было: image: paperlessngx/paperless-ngx:latest
image: paperlessngx/paperless-ngx:2.14.7
Во-вторых, завёл простой ритуал. Раз в пару недель смотрю, что вышло:
# что вообще доступно
docker compose -f /app/<сервис>/docker-compose.yml pull --dry-run
# а потом обязательно читаю changelog/release notes на гитхабе
И только если в release notes нет слов про «breaking changes», «migration» и «backup your data before upgrade» — обновляюсь. А если есть — сначала делаю бэкап томов, потом обновляю, потом проверяю, что всё живо.
# бэкап перед апгрейдом — стало рефлексом
docker run --rm -v paperless_data:/data -v $(pwd):/backup \
alpine tar czf /backup/paperless_data_$(date +%F).tar.gz -C /data .
Да, это медленнее. Да, иногда я неделю сижу на «старой» версии. Зато я точно знаю, что именно и когда поменялось, и если что-то сломается — это будет в удобное мне время, а не в 3:00 под аккомпанемент пуш-уведомлений.
Автоматизация хороша ровно до того момента, пока она не автоматизирует катастрофу. Обновление сервисов — как раз тот случай, где я предпочитаю держать руку на рубильнике сам.