
Как обновлять Docker Compose-сервис с миграциями и откатом
Готовим обновление Compose-приложения и базы данных: фиксируем образы, проверяем совместимость миграций, делаем копию, запускаем проверки и планируем откат.
Содержание
Обновить контейнер приложения легко, пока формат данных не меняется. С миграцией базы задача становится двухчастной: новый код должен понимать текущее состояние данных, а возврат старого кода — не ломаться после изменения схемы. Миграцией называют управляемое изменение структуры или содержимого базы: добавление столбца, индекса, таблицы либо преобразование записей.
Сначала определите совместимость
Для каждого релиза ответьте на три вопроса:
- Может ли текущая версия приложения работать после новой миграции?
- Может ли новая версия некоторое время работать до завершения преобразования данных?
- Есть ли проверенная копия и сколько займёт восстановление, если миграция необратима?
Самый спокойный переход строится по схеме «расширить — переключить — удалить». Сначала база получает новое необязательное поле или таблицу, которую старый код игнорирует. Затем новая версия начинает писать и читать новое представление. Удаление старого поля выполняется отдельным будущим релизом, когда возврат к прежнему коду уже не требуется.
Зафиксируйте исходное состояние
До скачивания новой версии сохраните хеш репозитория, итоговую Compose-конфигурацию и точные ссылки образов. Команды выполняются в каталоге проекта и только читают состояние:
git rev-parse HEAD
docker compose config --images
docker compose images
docker compose ps
В журнале релиза должны остаться digest или другой неизменяемый идентификатор каждого образа, а не только тег latest. Если Compose показывает локально собранный образ без понятной связи с коммитом, сначала исправьте процесс сборки.
Проверьте новую конфигурацию до остановки сервиса
Измените ссылки образов в compose.yaml, затем проверьте развёрнутую конфигурацию. pull скачивает новые слои, но не заменяет работающие контейнеры:
docker compose config --quiet
docker compose pull
docker compose images
Если registry недоступен, закончилось место или образ не существует для архитектуры сервера, остановитесь здесь. Текущий сервис продолжает работать, поэтому нет причины переходить к миграции с неполным набором образов.
Сделайте копию способом, подходящим базе
Docker volume сам по себе не является резервной копией: он находится на том же хосте и меняется вместе с рабочей базой. Перед миграцией создайте согласованную копию штатным средством СУБД и перенесите её вне VPS. Для PostgreSQL это обычно pg_dump или pg_dumpall, для MariaDB — mariadb-dump. Выбор формата, ролей и параметров зависит от базы и объёма.
После создания копии проверьте файл и восстановите его в отдельную тестовую базу. Простого наличия архива недостаточно. Пошаговый пример для volumes и ручного переноса на компьютер приведён в руководстве по резервному копированию Docker-данных.
Запускайте миграцию одной управляемой командой
В Compose-проекте полезно иметь отдельный сервис или профиль, который использует тот же образ приложения, но запускает штатный инструмент миграций. Его команда зависит от технологии: Django, Rails, Laravel, Prisma и собственные приложения используют разные интерфейсы. Не копируйте выдуманную универсальную команду из инструкции — возьмите точную команду из проекта и сначала выполните режим просмотра плана, если он поддерживается.
Перед изменением данных убедитесь, что миграцию запустит один процесс. Несколько одновременно стартующих экземпляров способны бороться за блокировки или повторно выполнить преобразование. Запишите время начала, версию образа и полный код завершения команды.
После успешной миграции снова выполните её штатную команду проверки статуса. Ожидаемый результат — нет ожидающих операций, а версия схемы соответствует релизу. Если команда завершилась неуспешно, не запускайте её снова автоматически: сначала прочитайте сообщение и определите, успела ли она изменить данные частично.
Замените сервис и сразу проверьте его
Когда база готова, пересоздайте только приложение и не трогайте volume. Команды ниже применяют новую конфигурацию, показывают состояние и последние сообщения сервиса web:
docker compose up -d --no-deps web
docker compose ps web
docker compose logs --tail 150 --timestamps web
Если контейнер имеет healthcheck, дождитесь healthy. Затем проверьте локальный адрес приложения и публичный маршрут через Nginx. В smoke-набор включите чтение старых записей, создание безопасной тестовой записи и повторное чтение, если такой сценарий разрешён для среды.
Не удаляйте старый образ сразу после успеха. Он нужен, пока не завершено окно наблюдения и не подтверждена совместимость данных.
Когда можно вернуть старый образ
Возврат к предыдущей ссылке образа допустим, если старая версия понимает текущую схему. Верните прежний digest в compose.yaml, проверьте конфигурацию и пересоздайте сервис:
docker compose config --quiet
docker compose up -d --no-deps web
docker compose ps web
docker compose logs --tail 100 web
Эти команды не откатывают миграцию. Если новая схема несовместима со старым кодом, варианты должны быть определены заранее: обратная миграция, восстановление проверенной копии с потерей более новых записей либо исправляющий релиз. Решение зависит от допустимой потери данных и времени простоя.
Ошибки, которые превращают обновление в аварию
- тег образа перемещён, а предыдущий digest не записан;
- новая версия и миграция запускаются одновременно на нескольких узлах;
- столбец удаляется в том же релизе, где код перестаёт его читать;
- копия существует только внутри того же Docker volume;
- восстановление ни разу не выполнялось;
docker compose down -vиспользуется как часть обновления;- ошибку миграции обходят повторным запуском без разбора частичного состояния;
- старые образы очищаются до окончания проверки.
Запишите результат релиза
После успешной публикации сохраните коммит, digest образов, версию схемы, время миграции, результат smoke-теста и путь к проверенной копии. Это превращает следующий сбой из угадывания в последовательную проверку.
Основы Compose разобраны в вводной главе, точный выбор версии — в материале о тегах и digest, а логи и состояние контейнера — в практикуме по диагностике.
Источники
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Откатывает ли возврат старого образа изменения базы данных?
Нет. Образ возвращает код, а данные остаются в новом состоянии. До релиза нужно подтвердить обратную совместимость миграции либо подготовить отдельное восстановление базы.
Зачем сначала скачивать образы командой docker compose pull?
Так ошибка доступа к registry или отсутствие нужного образа обнаруживается до остановки текущего сервиса. Запущенные контейнеры при pull не меняются.
Можно ли выполнять миграцию автоматически при каждом старте приложения?
Для нескольких экземпляров это создаёт гонку и смешивает запуск с изменением данных. Лучше иметь одну управляемую команду миграции с журналом и явным результатом.


