Перейти к содержанию

Backend — Blue-Green Deploy

Текущий статус: vpn-back-blue, порт 8080 Сервер: 10.99.87.249 CI/CD: GitLab project 33, auto deploy on push to main


Схема

GitLab CI push → build image → deploy.sh (container) → nginx switch → stop old

Два контейнера чередуются: vpn-back-blue:8080 и vpn-back-green:8081.


Фазы деплоя

Фаза 1: Запуск нового контейнера (deploy.sh)

Файл: /opt/deploy/deploy-backend.sh (синхронизируется из backend-app/docker/deploy.sh через CI)

  1. Определяет активный контейнер (blue/green) и свободный порт
  2. Запускает новый контейнер:
    docker run -d --name=$NEW -p $PORT:8080 \
      --env-file /opt/deploy/backend.env \
      --restart always $IMAGE
    
  3. Health check — 240 секунд ожидания ответа /actuator/health
  4. Если health check упал → новый контейнер удаляется, старый остаётся (автоматический откат)
  5. Сохраняет состояние в /opt/deploy/.deploy-state

Фаза 2: Переключение nginx (CI pipeline)

CI читает активный порт из .deploy-state и обновляет upstream в /opt/nginx/conf/vpn.conf через awk, затем делает nginx -s reload (без downtime).

Фаза 3: Остановка старого контейнера

/opt/deploy/deploy-backend.sh --stop-old

Graceful stop с таймаутом 25 секунд, затем docker rm.


Файл состояния

/opt/deploy/.deploy-state содержит:

ACTIVE_CONTAINER=vpn-back-blue
ACTIVE_PORT=8080
ACTIVE_IMAGE=10.99.87.8:5000/vpn-back:0bc5edd2
PREVIOUS_IMAGE=10.99.87.8:5000/vpn-back:3cc68129
OLD_CONTAINER=
DEPLOY_TIME=2026-03-02T15:41:06+00:00
COMMIT_SHA=0bc5edd2

Rollback

Откат ручной (в CI: when: manual).

./scripts/ssh-internal.sh 10.99.87.249 "/opt/deploy/deploy-backend.sh --rollback"

Скрипт запускает контейнер с PREVIOUS_IMAGE на альтернативном порту, проходит health check, переключает nginx, останавливает текущий.

Быстрый способ проверить что активно:

./scripts/ssh-internal.sh 10.99.87.249 "cat /opt/deploy/.deploy-state"
./scripts/ssh-internal.sh 10.99.87.249 "curl -sf http://localhost:8080/actuator/health"

Метрики (actuator)

Backend экспортирует метрики по адресу :8080/actuator/prometheus. Prometheus scrape настроен на 10.99.87.249:8080.

Nginx /etc/nginx/conf.d/backend-metrics.conf проксирует :8082 → :8080/actuator/ и захардкожен на порт 8080 — не обновляется при переключении на green (порт 8081). При смене активного контейнера на green метрики временно недоступны до ручного исправления.


Переменные окружения

Хранятся в /opt/deploy/backend.env (копируются из GitLab CI vars при каждом деплое).

GitLab переменные с $ — должны иметь флаг raw=true, иначе $ экранируется shell'ом.


Ссылки

  • backend-app/docker/deploy.sh — источник deploy-скрипта
  • backend-app/.gitlab-ci.yml, строки 193-342 — полный pipeline
  • GitLab project 33: https://git.karmann.tech/vpn/back

См. также: Репозитории · Runbooks · Логи · Backend ошибки · Архитектура бэкенда