Обновление контейнеров без простоя
Как обновлять образы так, чтобы сервис не лёг и можно было откатиться: фиксация версий, проверка здоровья, порядок действий и автоматизация.
Обновлено 23 августа 2026 г.
Обновление контейнера — это не «скачать новый образ», а «заменить работающую версию на новую и суметь вернуться назад». Разница видна ровно один раз: когда новая версия не запускается.
Порядок, который работает
cd /opt/myapp
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f --tail 100
Compose пересоздаёт только те службы, чей образ изменился, остальные не трогает. Простой — секунды на перезапуск контейнера.
Но прежде чем это делать, соблюдите два условия.
Первое: версии зафиксированы. В файле должно стоять postgres:17.2, а не postgres:latest. Иначе pull однажды принесёт мажорную версию, которая перепишет формат данных, и откат станет невозможен.
Второе: копия свежая. Обновление, которое ломает базу, ломает её необратимо. Перед сменой мажорной версии — выгрузка, см. что копировать.
Замена без разрыва
Для веб-сервиса за обратным прокси простой сводится почти к нулю, если у контейнера есть проверка здоровья: прокси начнёт слать запросы только в готовый экземпляр.
services:
app:
image: ghcr.io/example/app:1.5.0
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
interval: 5s
timeout: 3s
retries: 6
start_period: 20s
docker inspect -f '{{.State.Health.Status}}' <контейнер>
Без проверки здоровья Compose считает контейнер готовым сразу после старта процесса — а приложение в этот момент ещё читает настройки и накатывает миграции.
Не удаляйте старый образ, пока новая версия не проработала хотя бы час. Откат — это вернуть
image: ...:1.4.2и выполнитьdocker compose up -d, но только пока старый образ лежит на диске.docker image prune -aсразу после обновления лишает вас этой возможности.
Откат
sed -i 's|app:1.5.0|app:1.4.2|' compose.yaml
docker compose up -d app
docker compose logs -f --tail 50 app
Если новая версия успела изменить схему базы, одного отката образа мало — понадобится восстановление из копии. Поэтому мажорные обновления делают в спокойное время и с проверенной копией: см. учебное восстановление.
Автоматизация: осторожно
Watchtower умеет обновлять контейнеры сам. Для домашних сервисов это удобно, для боевых — риск: обновление приедет ночью, сломает базу, и никто не увидит. Разумный компромисс — только уведомления:
services:
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --monitor-only --schedule "0 0 6 * * *"
Вы узнаёте, что вышла новая версия, и обновляете руками в удобное время.
Перезагрузка машины
Пакеты системы обновляются отдельно от контейнеров. После обновления ядра нужна перезагрузка, и контейнеры с restart: unless-stopped поднимутся сами. Проверьте это заранее — командой sudo reboot в спокойное время, а не во время аварии. Мягкая перезагрузка из панели работает, пока в системе установлен qemu-guest-agent.
Частые ошибки
pullбезup -d. Новый образ скачан, но работает по-прежнему старый контейнер.- Диск забит старыми образами. Раз в месяц
docker image prune— но не сразу после обновления. См. место на диске. - Обновили всё разом. Ломается — непонятно что именно. Обновляйте по одной службе.
- Не прочитали примечания к выпуску. Несовместимый файл настройки — самая частая причина отказа после смены мажора; разбор — в частых проблемах Docker.