До основного вмісту

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: автоматизація налаштування серверів, а безпечний відкат усієї міграції цілком описано у статті план відкату міграції.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці