ci: Green-Blue 배포 + 마이그레이션 검증 + Nginx 검증 (taxbaik 패턴 적용)
Quant Engine CI/CD Pipeline / validate-core (push) Failing after 13s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (push) Has been skipped
Build & Package / build (push) Failing after 1m32s
Deploy to Production (Local) / Build & Deploy to Production (push) Failing after 1m27s

## 변경 사항

### 1. Green-Blue 배포 스크립트 (새로움: deploy_gb.sh)
taxbaik의 배포 전략을 QuantEngine에 맞춰 로컬화

**기능**:
- Phase 1: 새 버전(Green) 준비 (배포 중단 없음)
- Phase 2: 마이그레이션 사전 검증
- Phase 3: Nginx 설정 검증
- Phase 4: 데이터베이스 마이그레이션 준비 확인
- Phase 5: 원자적 전환 (Blue → Green)
- Phase 6: 서비스 재시작
- Phase 7: 이전 버전 정리 (최근 5개 유지)

**장점**:
- 배포 중단 최소화 (원자적 링크 전환)
- 즉각 롤백 가능 (이전 버전 유지)
- 단계별 검증으로 배포 안정성 ↑

### 2. 마이그레이션 검증 스크립트 (새로움: scripts/validate_migrations.sh)
배포 전 데이터베이스 상태 검증

**검증 항목**:
- 데이터베이스 연결 테스트
- 현재 마이그레이션 버전 확인
- DbUp 마이그레이션 파일 검증
- 필수 테이블 존재 확인
- 마이그레이션 호환성 (다운그레이드 방지)
- 마이그레이션 시간 예측

**효과**:
- 배포 전 데이터 무결성 보장
- 마이그레이션 실패 사전 차단
- 롤백 필요성 제거

### 3. deploy-prod.yml 통합
- 마이그레이션 검증을 배포 전에 실행
- Green-Blue 배포 스크립트 호출
- Nginx 설정 검증 추가
- 배포 이력 로깅

## 배포 흐름 (개선)

```yaml
1. 빌드 + 테스트
2. 패키지 생성 (tar.gz)
   ├─ deploy_gb.sh 포함
   └─ scripts/validate_migrations.sh 포함
3. Pre-Deployment 검증
   ├─ DB 연결 테스트
   ├─ 마이그레이션 호환성 확인
   └─ 필수 테이블 검증
4. Green-Blue 배포 (deploy_gb.sh)
   ├─ Green 버전 준비
   ├─ Nginx 설정 검증
   ├─ 원자적 링크 전환
   ├─ 서비스 재시작
   ├─ 자동 롤백 (실패 시)
   └─ 이전 버전 정리
5. 헬스체크 (3회)
6. Nginx 재검증
```

## 아키텍처 원칙

1. **무중단 배포** (Shadow Copy + Green-Blue)
   - 링크 전환 시에만 짧은 중단
   - 롤백 즉시 가능

2. **사전 검증** (Pre-Deployment)
   - 배포 전 모든 조건 확인
   - 배포 중단 최소화

3. **자동 복구** (Auto-Rollback)
   - 헬스체크 실패 시 이전 버전 복구
   - Telegram 자동 알림

## 다음 단계 (Phase 2)

- build.yml 활성화 (빌드 분리)
- Gitea Releases 활용 (아티팩트 저장)
- E2E 테스트 추가 (로그인, API)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 18:25:02 +09:00
parent 0d8e3a637f
commit db19f0cbd9
3 changed files with 397 additions and 23 deletions
+61 -23
View File
@@ -127,6 +127,15 @@ jobs:
echo "✓ Database configuration prepared"
- name: Copy Deployment Scripts
run: |
echo "📋 Copying deployment scripts..."
cp deploy_gb.sh ./publish/deploy_gb.sh
mkdir -p ./publish/scripts
cp scripts/validate_migrations.sh ./publish/scripts/validate_migrations.sh
chmod +x ./publish/deploy_gb.sh ./publish/scripts/validate_migrations.sh
echo "✓ Deployment scripts copied"
- name: Package Artifact
run: |
echo "📦 Creating deployment package..."
@@ -151,7 +160,23 @@ jobs:
echo "✓ Package created: $PACKAGE_SIZE"
tar -tzf quantengine.tar.gz | head -n 5 || true
- name: Local Deploy & Verify
- name: Pre-Deployment Migration Validation
run: |
echo "=== Pre-Deployment Database Check ==="
# 배포 패키지 임시 추출 (검증용)
TEMP_DEPLOY="/tmp/quantengine_validate"
mkdir -p "$TEMP_DEPLOY"
tar -xzf quantengine.tar.gz -C "$TEMP_DEPLOY"
# 마이그레이션 검증 실행
chmod +x "$TEMP_DEPLOY/scripts/validate_migrations.sh"
"$TEMP_DEPLOY/scripts/validate_migrations.sh" "$TEMP_DEPLOY"
# 정리
rm -rf "$TEMP_DEPLOY"
- name: Local Deploy (Green-Blue)
id: deploy
run: |
set -e
@@ -180,37 +205,29 @@ jobs:
mkdir -p "${DEPLOY_BASE}"
mkdir -p "${TARGET_DIR}"
# 이전 버전 저장
if [ -L "${ACTIVE_LINK}" ]; then
PREV_VERSION=$(readlink -f "${ACTIVE_LINK}")
PREV_TIMESTAMP=$(basename "${PREV_VERSION}")
else
PREV_VERSION="none"
PREV_TIMESTAMP="none"
fi
echo "Previous deployment: ${PREV_VERSION}"
# 배포 패키지 추출
echo "📁 Extracting build artifact to ${TARGET_DIR}..."
echo "📁 Extracting build artifact..."
tar -xzf quantengine.tar.gz -C "${TARGET_DIR}"
rm -f quantengine.tar.gz
# 심볼릭 링크 교체 (Shadow Copy 배포)
echo "🔄 Swapping symbolic link..."
ln -sfn "${TARGET_DIR}" "${ACTIVE_LINK}"
# 환경 파일 설치
echo "⚙️ Installing environment configuration..."
mkdir -p /home/kjh2064/.config
install -m 600 ./deploy/quantengine.env /home/kjh2064/.config/quantengine.env
# 서비스 재시작
echo "🚀 Restarting service..."
sudo systemctl restart quantengine
# Green-Blue 배포 실행
echo "🚀 Executing Green-Blue Deployment..."
export DEPLOY_FROM_CI=1
chmod +x "${TARGET_DIR}/deploy_gb.sh"
"${TARGET_DIR}/deploy_gb.sh"
# 서비스 안정화 대기
echo "⏳ Waiting for service stabilization (5s)..."
sleep 5
# 이전 버전 정보 저장
if [ -L "${ACTIVE_LINK}" ]; then
PREV_VERSION=$(readlink -f "${ACTIVE_LINK}")
PREV_TIMESTAMP=$(basename "${PREV_VERSION}")
else
PREV_TIMESTAMP="none"
fi
echo "timestamp=${TIMESTAMP}" >> $GITHUB_OUTPUT
echo "commit=${COMMIT}" >> $GITHUB_OUTPUT
@@ -304,8 +321,29 @@ jobs:
echo "⚠️ Unexpected login page response: $login_code"
fi
echo "=== Verifying Nginx Configuration ==="
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 [ -n "$NGINX_CONF" ]; then
echo "✓ Nginx configuration found: $NGINX_CONF"
if nginx -t > /dev/null 2>&1; then
echo "✓ Nginx syntax validated"
else
echo "⚠️ Nginx syntax check failed (service may still work)"
fi
else
echo "⚠️ Nginx configuration not found"
echo " Expected: /etc/nginx/sites-enabled/* with 'location /quantengine'"
fi
echo "✓ 배포 완료: quantengine_${TIMESTAMP}"
send_telegram "✅ <b>QuantEngine 배포 완료</b>
send_telegram "✅ <b>QuantEngine 배포 완료 (Green-Blue)</b>
커밋: <code>${COMMIT}</code>
시간: <code>${TIMESTAMP}</code>