Blue-green деплой на VPS
Blue-green держит две идентичные среды: одна принимает трафик, вторая обновляется. Переключение — одна правка в nginx, откат — такая же. Реализуем схему на одном VPS с прогревом и проверкой перед свитчем.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Идея blue-green
Есть две среды — blue и green — с одинаковым кодом и конфигом, но разными портами. В любой момент трафик идёт только в одну из них, вторая свободна для деплоя.
Цикл выката: обновляем неактивную среду, прогреваем и проверяем её, затем переключаем трафик. Если что-то не так — мгновенно возвращаем на прежнюю среду, ведь она всё это время работала.
Blue-green держит одновременно две копии приложения, поэтому RAM нужно с запасом. На тарифах MAATRIX легко взять конфигурацию, где обе среды помещаются без свопа, а NVMe ускоряет прогрев кэшей после старта. Если приложение уйдёт в своп во время выката, отклик просядет ровно в момент переключения — а именно этого blue-green и призван избежать.
Главное отличие от симлинк-деплоя в том, что старая версия продолжает работать, а не просто лежит на диске. Откат мгновенный, потому что откатываться некуда идти — прежняя среда уже поднята и готова принять трафик обратно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS для blue-green деплояДве среды в docker-compose
Опишем два стека, различающихся только именем и внешним портом. blue слушает 8001, green — 8002.
# docker-compose.blue.yml
services:
app-blue:
image: myapp:${TAG}
ports: [ "127.0.0.1:8001:8000" ]
environment:
COLOR: blue
# docker-compose.green.yml
services:
app-green:
image: myapp:${TAG}
ports: [ "127.0.0.1:8002:8000" ]
environment:
COLOR: green
TAG=v42 docker compose -f docker-compose.green.yml up -d
Переключение через nginx
Активный апстрим держим в отдельном подключаемом файле. nginx читает upstream_active.conf, а скрипт деплоя просто меняет его содержимое и делает reload.
# /etc/nginx/conf.d/upstream_active.conf
upstream active {
server 127.0.0.1:8001; # сейчас blue
}
# основной конфиг
server {
location / { proxy_pass http://active; }
}
Переключение на green — заменить порт и перечитать конфиг без разрыва соединений:
echo 'upstream active { server 127.0.0.1:8002; }' \
> /etc/nginx/conf.d/upstream_active.conf
nginx -t && systemctl reload nginx
Прогрев и проверка перед свитчем
Никогда не переключайте трафик на непроверенную среду. Сначала дождитесь, пока green ответит на healthcheck, и прогрейте основные эндпоинты.
#!/bin/bash
set -e
NEW=8002
# ждём готовности
for i in $(seq 1 20); do
curl -fs http://127.0.0.1:$NEW/health && ready=1 && break
sleep 1
done
[ "$ready" = 1 ] || { echo "green не поднялся"; exit 1; }
# прогрев
curl -s http://127.0.0.1:$NEW/ > /dev/null
curl -s http://127.0.0.1:$NEW/api/status > /dev/null
# переключаем
echo "upstream active { server 127.0.0.1:$NEW; }" \
> /etc/nginx/conf.d/upstream_active.conf
nginx -t && systemctl reload nginx
echo "switched to $NEW"
Мгновенный откат
Старая среда после переключения не гасится сразу — держите её живой ещё несколько минут. Если на новой всплыл баг, откат — это возврат прежнего порта.
echo 'upstream active { server 127.0.0.1:8001; }' \
> /etc/nginx/conf.d/upstream_active.conf
nginx -t && systemctl reload nginx
Убедившись, что новая среда стабильна, старую можно остановить, освободив ресурсы:
docker compose -f docker-compose.blue.yml down
Хорошая практика — держать между переключениями «карантинную» паузу в 5–10 минут и следить за метриками ошибок новой среды. Если процент 5xx или время отклика поползли вверх, откат делается до того, как проблему заметят пользователи. Автоматизировать это можно скриптом, который сравнивает частоту ошибок и сам возвращает трафик при превышении порога.
Частые ошибки
- Общая БД с несовместимой схемой — обе среды ходят в одну базу, миграция ломает старую. Делайте совместимые миграции.
- Погасили старую среду сразу — откатываться некуда. Держите её живой ещё несколько минут.
- Переключились без healthcheck — увели трафик на упавшую среду.
- Порты наружу — 8001/8002 должны слушать только 127.0.0.1, не публичный интерфейс.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS для blue-green деплояОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Чем blue-green отличается от canary?
Blue-green переключает 100% трафика разом. Canary направляет сначала небольшую долю на новую версию и наращивает её постепенно.
Blue-green требует в два раза больше ресурсов?
На время выката — да, работают обе среды. Поэтому берите VPS с запасом RAM, чтобы две копии помещались одновременно.
Как быть с общей базой данных?
База одна на обе среды. Меняйте схему обратно-совместимо, чтобы и старый, и новый код работали с ней одновременно.