#Azure#Cloud#GitLab#CI/CD#Nginx#Blue/Green#Shell
GitLab Runner(Shell Executor)를 통한 Nginx의 Blue/Green 배포
GitLab CI를 활용한 Nginx Blue/Green 배포 파이프라인 구성
Azure VM에서 GitLab, GitLab Runner, Nginx를 사용한 무중단 블루/그린 배포 구축.
파이프라인이 실행됐을 때 슬롯을 변경하도록 하고, 수동으로 전환 또한 가능하게 한다.
Github Source Code
☑️ 구축 목표
- GitLab(Omnibus)은 80/443 포트를 그대로 사용, 애플리케이션 트래픽은 8081번 포트의 Edge Nginx가 담당
- Blue/Green 슬롯은 각각의 컨테이너(app-blue, app-green)로 항상 기동
- 심볼릭 링크를 교체한 뒤
nginx -s reload를 호출하면 즉시 전환 - GitLab Runner가 태그 푸시를 감지해 배포 → 검증 → 전환 → 지연 정리까지 자동 실행
☑️ 환경 구성
- Azure VM (Standard_B4ms, Ubuntu)
- Docker / Docker Compose v2
- GitLab Omnibus + GitLab Runner(Shell)
☑️ 웹 서버 컨테이너 구성

[Client]
↓
http://<VM>:8081 (Edge Nginx)
├─ / → app_active (blue 또는 green)
├─ /_blue/ → app-blue (Nginx 컨테이너)
└─ /_green/ → app-green (Apache 컨테이너)
- Edge Nginx가 단일 엔드포인트 역할
app_active.conf가 현재 슬롯을 가리키며, 심볼릭 링크 교체로 전환- GitLab Runner와 애플리케이션 컨테이너는 동일 VM에 위치
☑️ 초기 설정
-
GitLab Runner 등록 과정에서 Shell Executor를 붙여 놓았다.

☑️ 디렉터리 구조
nginx-apache-blue-green
├── app
│ ├── blue/www/index.html
│ ├── green/www/index.html
│ ├── docker-compose.blue.yml
│ └── docker-compose.green.yml
├── nginx
│ ├── conf.d/app_active.conf -> app_blue.conf
│ ├── conf.d/app_blue.conf
│ ├── conf.d/app_green.conf
│ ├── docker-compose.nginx.yml
│ └── nginx.conf
└── scripts
├── deploy_green.sh
├── retire_old.sh
├── rollback.sh
└── switch_traffic.sh
두 슬롯을 동시에 띄우고, 스크립트에서 심볼릭 링크와 Compose 프로젝트명을 적절히 다루는 것이 핵심이다.
☑️ 파이프라인 흐름
1. 태그 푸시 또는 수동 실행으로 배포 파이프라인 시작

2. bootstrap 단계에서 환경 점검 및 기본 링크 설정

3. 이후 배포 진행 후 검증
bootstrap -> deploy -> verify -> switch 과정 진행 (cleanup은 30분 후 스케줄링)

- 현재 활성 슬롯을 확인해 반대 슬롯으로 전환
Blue가 활성이면 →Green으로 전환Green이 활성이면 →Blue로 전환
☑️ 결과
1. 파이프라인 실행 전/후

2. GitLab UI에 전환용 수동(Job) 버튼을 추가해, 파이프라인을 돌지 않고 롤백도 가능

☑️ Troubleshooting
1. Nginx 체크 포인트
# nginx.conf
upstream app_blue { server app-blue:80; keepalive 64; }
upstream app_green { server app-green:80; keepalive 64; }
# 활성 슬롯만 include
include /etc/nginx/conf.d/app_active.conf;
app_active.conf는app_blue.conf또는app_green.conf에 대한 심볼릭 링크- 링크 교체는 항상 원자적으로 수행 (
ln -sfn,mv -Tf)해 중간 상태를 방지 - Nginx 설정 변경 후에는
nginx -t로 검증한 뒤nginx -s reload
2. Docker Compose 프로젝트 분리
deploy 파이프라인 실패

# bootstrap
docker compose -p bg-blue -f app/docker-compose.blue.yml up -d
docker compose -p bg-green -f app/docker-compose.green.yml up -d
- bootstrap에서
-p로 올렸으면, deploy/cleanup에서도 반드시 같은-p를 써야 컨테이너 이름 충돌이 나지 않는다.
3. GitLab CI 체크 포인트
bootstrap 파이프라인 실패

before_script:
- set -euo pipefail
- docker --version
- docker compose version
- 파이프라인 초반에 환경 이상(Compose v2 미설치, runner 태그 미일치) 발견
- Runner 환경이 예상과 다를 경우 즉시 실패하도록
set -euo pipefail