К основному содержимому

Zero-downtime деплой: blue-green и rolling стратегии

Миграция · 04.02.2025 · 4 мин чтения
Иллюстрация к статье «Zero-downtime деплой: blue-green и rolling стратегии»

Порядок деплоя, при котором сайт не отдаёт 502

Zero-downtime не значит «без риска» — значит «без видимого для пользователя перерыва». Это достигается тем, что новая версия поднимается и проверяется рядом со старой, а переключение происходит одной атомарной операцией, которую легко отменить.

  1. Разверните новую версию приложения на отдельном порту или в отдельном контейнере, не трогая работающую.
  2. Дождитесь, пока новая версия пройдёт health-check и полностью инициализируется (прогреет кеш, подключится к базе).
  3. Проверьте новую версию напрямую, минуя основной домен — через прямой порт или служебный заголовок.
  4. Переключите балансировщик или прокси на новую версию одной командой.
  5. Держите старую версию запущенной ещё некоторое время — на случай, если понадобится мгновенный откат.

Честно: полностью нулевого простоя не бывает даже при таком порядке — остаётся доля секунды на переключение соединений в момент reload. На практике это означает 0–2 секунды видимой задержки для части запросов, а не полное отсутствие эффекта.

Blue-Green деплой

Поддерживаем два идентичных окружения: Blue (текущий live) и Green (новая версия). После тестирования Green — переключаем трафик.

# Nginx upstream — переключение между blue и green
upstream app {
    server 127.0.0.1:8080;  # blue
    # server 127.0.0.1:8081;  # green (раскомментировать при переключении)
}

server {
    location / {
        proxy_pass http://app;
    }
}

Blue-Green с Docker Compose

# Запускаем green окружение
docker-compose -f docker-compose.green.yml up -d

# Проверяем green
curl http://localhost:8081/health

# Переключаем Nginx на green
sed -i 's/8080/8081/' /etc/nginx/conf.d/app.conf
nginx -s reload

# Останавливаем blue
docker-compose -f docker-compose.blue.yml down
💡 Blue-Green позволяет мгновенный откат: если green не работает — переключите Nginx обратно на blue одной командой.

Rolling Deployment

Постепенная замена инстансов: обновляем один за другим, не останавливая сервис.

# Пример с Docker Swarm
docker service update   --image myapp:v2   --update-parallelism 1   --update-delay 30s   myapp_service

Сравнение стратегий деплоя

СтратегияОткатРесурсыСложность
Blue-GreenМгновенный2xСредняя
RollingПостепенный1x + overheadНизкая
CanaryПостепенный1xВысокая

Проверка новой версии до переключения трафика

Не полагайтесь на визуальный осмотр — проверяйте health-check эндпоинт и реальный сценарий работы приложения напрямую на новом порту, до того как переключить прокси:

curl -s http://127.0.0.1:8081/health | grep -q '"status":"ok"' && echo "Green готов"

Здоровый эндпоинт должен проверять не только «процесс запущен», но и реальные зависимости: подключение к базе данных, доступность кеша, готовность очереди задач.

Типичные ошибки при переключении

СимптомПричина и решение
502 Bad Gateway сразу после reloadНовый апстрим ещё не принимает соединения — добавьте health-check перед переключением Nginx
Часть запросов идёт на старую версию после переключенияKeep-alive соединения с воркерами Nginx не сброшены — используйте nginx -s reload, а не restart
Ошибки схемы БД после деплоя новой версииМиграция базы несовместима со старой версией кода, которая ещё работает параллельно

Откат при неудачном деплое

  1. Не останавливайте старую версию (blue), пока новая не отработала под реальным трафиком минимум 15–30 минут.
  2. При проблемах верните upstream на старый порт — команда идентична переключению, только в обратную сторону.
  3. Разберитесь с причиной сбоя на green-окружении отдельно, не мешая рабочему трафику.

Когда это не подходит

Blue-Green требует вдвое больше ресурсов на время деплоя — для небольших проектов с ограниченным бюджетом это может быть неоправданно. Если приложение хранит состояние в памяти процесса (сессии, WebSocket-соединения) без внешнего хранилища, при переключении эти данные теряются — нужна отдельная схема с sticky-сессиями или внешним хранилищем состояния.

⚠️ При blue-green деплое убедитесь что оба окружения работают с одной базой данных и схема БД совместима с обеими версиями приложения.

Проверка результата после переключения

  • Мониторьте частоту ошибок 5xx в логах несколько минут после переключения — всплеск указывает на проблему.
  • Проверьте, что старые открытые сессии пользователей не разорвались.
  • Убедитесь, что фоновые задачи (очереди, cron) не выполняются дважды на старой и новой версии одновременно.

Настройку серверов через Ansible перед регулярными деплоями удобно автоматизировать — см. статью Ansible: автоматизация настройки серверов, а безопасный откат всей миграции целиком описан в статье план отката миграции.

Статья помогла?
← Назад в базу знаний Задать вопрос поддержке