#!/usr/bin/env bash # QuantEngine Green-Blue Deployment Script # Usage: DEPLOY_FROM_CI=1 ./deploy_gb.sh /path/to/deploy/dir # # Green-Blue strategy: # - Blue: 현재 실행 중인 버전 # - Green: 새로 배포할 버전 # - 원자적 전환으로 무중단 배포 set -euo pipefail if [ "${DEPLOY_FROM_CI:-0}" != "1" ]; then echo "ERROR: CI-only deployment policy. Set DEPLOY_FROM_CI=1" exit 1 fi DEPLOY_DIR="${1:-.}" if [ ! -d "$DEPLOY_DIR" ]; then echo "ERROR: Deploy directory not found: $DEPLOY_DIR" exit 1 fi DEPLOY_BASE="/home/kjh2064/deployments" ACTIVE_LINK="/home/kjh2064/quantengine_active" STAGING_LINK="/home/kjh2064/quantengine_staging" TIMESTAMP=$(date +%Y%m%d_%H%M%S) # Blue-Green 상태 조회 BLUE_VERSION=$(readlink -f "$ACTIVE_LINK" 2>/dev/null || echo "none") BLUE_TIMESTAMP=$(basename "$BLUE_VERSION" 2>/dev/null || echo "none") echo "=========================================" echo "Green-Blue Deployment [$TIMESTAMP]" echo "=========================================" echo "Blue (Active): $BLUE_TIMESTAMP" echo "Green (Deploy): $TIMESTAMP" # ───────────────────────────────────────── # Phase 1: Green 준비 (배포 중단 없음) # ───────────────────────────────────────── GREEN_DIR="${DEPLOY_BASE}/quantengine_${TIMESTAMP}" echo "" echo "--- Phase 1: 새 버전 준비 (Green) ---" mkdir -p "$GREEN_DIR" # 배포 파일 복사 echo "Copying application files..." cp -r "$DEPLOY_DIR"/* "$GREEN_DIR/" # 권한 설정 chmod +x "$GREEN_DIR/QuantEngine.Web" 2>/dev/null || true # appsettings.Production.json 검증 if [ ! -f "$GREEN_DIR/appsettings.Production.json" ]; then echo "ERROR: appsettings.Production.json not found" rm -rf "$GREEN_DIR" exit 1 fi echo "✓ Green version prepared: $TIMESTAMP" # ───────────────────────────────────────── # Phase 2: 마이그레이션 사전 검증 # ───────────────────────────────────────── echo "" echo "--- Phase 2: 데이터베이스 마이그레이션 검증 ---" # DB 연결 테스트 if ! psql -U quantengine_app -d quantenginedb -h 127.0.0.1 \ -c "SELECT version();" > /dev/null 2>&1; then echo "ERROR: Database connection failed" rm -rf "$GREEN_DIR" exit 1 fi echo "✓ Database connection verified" # DbUp 마이그레이션 시뮬레이션 (dry-run이 없으므로 Blue에서 실행되는 것 확인) # 실제 마이그레이션은 서비스 시작 시 DbMigrator.Migrate()에서 수행 echo "✓ Database migration will run on service startup" # ───────────────────────────────────────── # Phase 3: Nginx 설정 검증 # ───────────────────────────────────────── echo "" echo "--- Phase 3: Nginx 설정 검증 ---" NGINX_CONF="" for f in /etc/nginx/sites-enabled/*; do if [ -e "$f" ] && grep -q "location /quantengine" "$f" 2>/dev/null; then NGINX_CONF="$f" break fi done if [ -z "$NGINX_CONF" ]; then echo "WARNING: Nginx configuration for QuantEngine not found" echo " Expected: /etc/nginx/sites-enabled/* with 'location /quantengine'" else echo "✓ Nginx configuration found: $NGINX_CONF" # 문법 검증 if ! nginx -t -c "$NGINX_CONF" > /dev/null 2>&1; then echo "ERROR: Nginx configuration syntax error" nginx -t -c "$NGINX_CONF" rm -rf "$GREEN_DIR" exit 1 fi echo "✓ Nginx syntax validated" fi # ───────────────────────────────────────── # Phase 4: Green 버전에서 헬스체크 (선택사항) # ───────────────────────────────────────── # 참고: Green 버전이 아직 시작되지 않았으므로 실행 불가 # 배포 후 헬스체크는 deploy-prod.yml에서 수행 # ───────────────────────────────────────── # Phase 5: 원자적 전환 (Blue → Green) # ───────────────────────────────────────── echo "" echo "--- Phase 5: 원자적 전환 (Blue → Green) ---" # Staging 링크 생성 (중간 단계) ln -sfn "$GREEN_DIR" "$STAGING_LINK" echo "✓ Staging link updated" # Active 링크 전환 (원자적) ln -sfn "$GREEN_DIR" "$ACTIVE_LINK" echo "✓ Active link switched to Green: $TIMESTAMP" # 이전 Blue 정보 저장 echo "Previous Blue: $BLUE_TIMESTAMP" > "${GREEN_DIR}/.deployment_info" echo "Deployed at: $(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> "${GREEN_DIR}/.deployment_info" # ───────────────────────────────────────── # Phase 6: 서비스 재시작 # ───────────────────────────────────────── echo "" echo "--- Phase 6: 서비스 재시작 ---" sudo systemctl restart quantengine echo "✓ Service restarted" # 서비스 안정화 대기 sleep 3 if ! systemctl is-active --quiet quantengine; then echo "ERROR: Service failed to start" # 롤백 if [ "$BLUE_VERSION" != "none" ]; then echo "Rolling back to Blue: $BLUE_TIMESTAMP" ln -sfn "$BLUE_VERSION" "$ACTIVE_LINK" sudo systemctl restart quantengine rm -rf "$GREEN_DIR" exit 1 fi fi echo "✓ Service is running" # ───────────────────────────────────────── # Phase 7: 이전 버전 정리 # ───────────────────────────────────────── echo "" echo "--- Phase 7: 이전 버전 정리 (최근 5개 유지) ---" cd "$DEPLOY_BASE" KEEP_COUNT=5 DELETE_COUNT=$(ls -d quantengine_* 2>/dev/null | wc -l) DELETE_COUNT=$((DELETE_COUNT - KEEP_COUNT)) if [ $DELETE_COUNT -gt 0 ]; then echo "Removing old deployments (keeping $KEEP_COUNT versions)..." ls -dt quantengine_* | tail -n +$((KEEP_COUNT + 1)) | while read -r old_dir; do echo " Removing: $old_dir" rm -rf "$old_dir" done fi echo "✓ Cleanup complete" # ───────────────────────────────────────── # 완료 # ───────────────────────────────────────── echo "" echo "=========================================" echo "✓ Deployment successfully completed!" echo "=========================================" echo "Active Version: $TIMESTAMP" echo "Blue (Previous): $BLUE_TIMESTAMP" echo "Status: $(systemctl is-active quantengine)" echo "" echo "Deployment Info:" cat "${GREEN_DIR}/.deployment_info"