#!/bin/bash # Quant Engine Production Deployment Script (v9) # 환경: hz-prod-01, 공인IP 178.104.200.7, 내부 172.17.0.1 # 배포 경로: /home/kjh2064/quantengine_active # Nginx 설정: /etc/nginx/sites-available/gitea-ip.conf (reverse proxy → localhost:5000) set -e # ═══════════════════════════════════════════════════════════════ # 설정 # ═══════════════════════════════════════════════════════════════ DEPLOY_HOST="178.104.200.7" DEPLOY_INTERNAL_IP="172.17.0.1" DEPLOY_USER="kjh2064" DEPLOY_PATH="/home/kjh2064/quantengine_active" SERVICE_NAME="quantengine" BACKUP_PATH="/home/kjh2064/quantengine_backup" LOCAL_PUBLISH_DIR="$(pwd)/src/dotnet/QuantEngine.Web/publish" echo "🚀 Quant Engine v9 Production Deployment" echo "═══════════════════════════════════════════════════════════════" echo "Public URL: http://$DEPLOY_HOST/quant/" echo "Internal IP: $DEPLOY_INTERNAL_IP" echo "Deploy Path: $DEPLOY_PATH" echo "Service: $SERVICE_NAME" echo "Backup Path: $BACKUP_PATH" echo "Hostname: hz-prod-01" echo "═══════════════════════════════════════════════════════════════" echo "" # ═══════════════════════════════════════════════════════════════ # Step 1: 배포 파일 준비 # ═══════════════════════════════════════════════════════════════ echo "📦 Step 1: 배포 파일 확인..." if [ ! -d "$LOCAL_PUBLISH_DIR" ]; then echo "❌ 오류: $LOCAL_PUBLISH_DIR 없음" echo "먼저 'dotnet publish -c Release'를 실행하세요" exit 1 fi PACKAGE_SIZE=$(du -sh "$LOCAL_PUBLISH_DIR" | cut -f1) FILE_COUNT=$(find "$LOCAL_PUBLISH_DIR" -type f | wc -l) echo "✓ 배포 패키지:" echo " 크기: $PACKAGE_SIZE" echo " 파일 수: $FILE_COUNT" echo "" # ═══════════════════════════════════════════════════════════════ # Step 2: SSH 연결 확인 # ═══════════════════════════════════════════════════════════════ echo "🔐 Step 2: SSH 연결 확인..." if ! ssh -o ConnectTimeout=10 "$DEPLOY_USER@$DEPLOY_HOST" "echo '✅ SSH 연결 성공'" &>/dev/null; then echo "❌ SSH 연결 실패" exit 1 fi echo "✓ SSH 연결 확인됨" echo "" # ═══════════════════════════════════════════════════════════════ # Step 3: 배포 전 확인 # ═══════════════════════════════════════════════════════════════ echo "✅ 배포 전 확인:" echo " [ ] Release 빌드 완료됨 ($PACKAGE_SIZE)" echo " [ ] SSH 연결 가능" echo "" read -p "배포를 진행하시겠습니까? (y/n) " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "❌ 배포 취소됨" exit 1 fi echo "" # ═══════════════════════════════════════════════════════════════ # Step 4: 서비스 중지 및 백업 생성 # ═══════════════════════════════════════════════════════════════ echo "🛑 Step 3: 서비스 중지 및 백업 생성..." ssh "$DEPLOY_USER@$DEPLOY_HOST" << 'EOF' set -e SERVICE_NAME="quantengine" DEPLOY_PATH="/home/kjh2064/quantengine_active" BACKUP_PATH="/home/kjh2064/quantengine_backup" BACKUP_NAME="quantengine_$(date +%Y%m%d_%H%M%S)" echo " 서비스 중지 중..." sudo systemctl stop "$SERVICE_NAME" 2>/dev/null || true sleep 2 echo " ✓ 서비스 중지 완료" echo " 백업 생성 중..." mkdir -p "$BACKUP_PATH" if [ -d "$DEPLOY_PATH" ]; then cp -r "$DEPLOY_PATH" "$BACKUP_PATH/$BACKUP_NAME" echo " ✓ 백업 생성: $BACKUP_PATH/$BACKUP_NAME" # 최근 5개만 유지 BACKUP_COUNT=$(ls -1 "$BACKUP_PATH" | wc -l) if [ "$BACKUP_COUNT" -gt 5 ]; then OLD_BACKUPS=$(ls -1t "$BACKUP_PATH" | tail -n +6) for backup in $OLD_BACKUPS; do rm -rf "$BACKUP_PATH/$backup" echo " 🧹 오래된 백업 삭제: $backup" done fi else echo " ⚠️ 기존 배포 없음 (첫 배포)" mkdir -p "$DEPLOY_PATH" fi EOF echo "" # ═══════════════════════════════════════════════════════════════ # Step 5: 파일 전송 # ═══════════════════════════════════════════════════════════════ echo "📤 Step 4: 파일 전송 (rsync)..." rsync -avz --delete \ --rsh="ssh" \ "$LOCAL_PUBLISH_DIR/" \ "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/" echo "✓ 파일 전송 완료" echo "" # ═══════════════════════════════════════════════════════════════ # Step 6: 서비스 시작 # ═══════════════════════════════════════════════════════════════ echo "🚀 Step 5: 서비스 시작..." ssh "$DEPLOY_USER@$DEPLOY_HOST" << 'EOF' set -e SERVICE_NAME="quantengine" DEPLOY_PATH="/home/kjh2064/quantengine_active" echo " 파일 검증 중..." if [ -f "$DEPLOY_PATH/QuantEngine.Web.dll" ]; then echo " ✓ QuantEngine.Web.dll 확인됨" else echo " ❌ QuantEngine.Web.dll 없음 (배포 실패)" exit 1 fi echo " 서비스 시작 중..." sudo systemctl start "$SERVICE_NAME" sleep 3 if sudo systemctl is-active --quiet "$SERVICE_NAME"; then echo " ✓ $SERVICE_NAME 시작 완료" else echo " ❌ $SERVICE_NAME 시작 실패" sudo systemctl status "$SERVICE_NAME" || true exit 1 fi EOF echo "" # ═══════════════════════════════════════════════════════════════ # Step 7: 헬스 체크 # ═══════════════════════════════════════════════════════════════ echo "🧪 Step 6: 헬스 체크..." for i in {1..30}; do HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ "http://$DEPLOY_HOST/quant/" 2>/dev/null || echo "000") if [ "$HTTP_CODE" = "200" ]; then echo "✓ Health check PASS (HTTP 200)" break fi echo " 시도 $i/30: HTTP $HTTP_CODE (대기 중...)" sleep 2 done echo "" # ═══════════════════════════════════════════════════════════════ # 배포 완료 # ═══════════════════════════════════════════════════════════════ echo "═══════════════════════════════════════════════════════════════" echo "✅ 배포 완료!" echo "═══════════════════════════════════════════════════════════════" echo "" echo "📊 배포 정보:" echo " 공인 URL: http://$DEPLOY_HOST/quant/" echo " 내부 IP: $DEPLOY_INTERNAL_IP" echo " 배포 경로: $DEPLOY_PATH" echo " 서비스: $SERVICE_NAME" echo " 백업: $BACKUP_PATH" echo "" echo "🔍 로그 확인:" echo " ssh $DEPLOY_USER@$DEPLOY_HOST 'sudo journalctl -u $SERVICE_NAME -f'" echo "" echo "🔄 롤백 (필요시):" echo " ssh $DEPLOY_USER@$DEPLOY_HOST << 'ROLLBACK'" echo " LATEST=\$(ls -t $BACKUP_PATH | head -1)" echo " cp -r $BACKUP_PATH/\$LATEST/* $DEPLOY_PATH/" echo " sudo systemctl restart $SERVICE_NAME" echo " ROLLBACK" echo "" echo "🌐 Nginx 역방향 프록시 구조:" echo " 공인 IP:178.104.200.7/quant/ → localhost:5000 (Nginx reverse proxy)" echo " Nginx 설정: /etc/nginx/sites-available/gitea-ip.conf" echo ""