feat(deploy): Add production deployment scripts for v9 quantengine

Add deploy-production.sh (new):
- Automated deployment to hz-prod-01 (178.104.200.7)
- Service lifecycle management: systemctl stop/start quantengine
- Automatic backup to /home/kjh2064/quantengine_backup
- File transfer via rsync to /home/kjh2064/quantengine_active
- Health checks against public URL and service status
- Rollback instructions with backup restoration

Update deploy-manual.sh:
- Interactive deployment with user confirmation
- Updated for quantengine service (not nginx)
- Deployment path: /home/kjh2064/quantengine_active
- Backup path: /home/kjh2064/quantengine_backup
- Nginx reverse proxy structure documentation
- Comprehensive rollback procedures

Both scripts:
- SSH connection validation (178.104.200.7)
- Environment diagnostics
- Comprehensive logging and error handling
- Support for internal and public IP access
- Pre/post deployment validation

Deployment Architecture:
Public: http://178.104.200.7/quant/
  → Nginx (reverse proxy)
  → localhost:5000 (quantengine service)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-06-25 18:23:54 +09:00
parent 762335286c
commit a2acaa70d8
2 changed files with 304 additions and 52 deletions
+75 -48
View File
@@ -1,6 +1,8 @@
#!/bin/bash #!/bin/bash
# Quant Engine Manual Deployment Script # Quant Engine Manual Deployment Script (v9)
# 원격 서버에 직접 SSH 접속하여 환경 파악 후 배포 # 환경: hz-prod-01 (178.104.200.7/172.17.0.1)
# 배포 경로: /home/kjh2064/quantengine_active
# 서비스: quantengine (systemd)
set -e set -e
@@ -8,18 +10,23 @@ set -e
# 설정 # 설정
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
DEPLOY_HOST="${1:-192.168.123.100}" DEPLOY_HOST="${1:-178.104.200.7}"
DEPLOY_USER="kjh2064" DEPLOY_USER="kjh2064"
SSH_KEY="${HOME}/.ssh/id_ed25519" SSH_KEY="${HOME}/.ssh/id_ed25519"
LOCAL_PUBLISH_DIR="$(pwd)/src/dotnet/QuantEngine.Web/publish" LOCAL_PUBLISH_DIR="$(pwd)/src/dotnet/QuantEngine.Web/publish"
REMOTE_DEPLOY_PATH="/var/www/quant" REMOTE_DEPLOY_PATH="/home/kjh2064/quantengine_active"
REMOTE_BACKUP_PATH="/home/kjh2064/quantengine_backup"
SERVICE_NAME="quantengine"
echo "🚀 Quant Engine Manual Deployment" echo "🚀 Quant Engine v9 Manual Deployment"
echo "═══════════════════════════════════════════════════════════════" echo "═══════════════════════════════════════════════════════════════"
echo "Deploy Host: $DEPLOY_HOST" echo "Deploy Host: $DEPLOY_HOST"
echo "Deploy User: $DEPLOY_USER" echo "Deploy User: $DEPLOY_USER"
echo "Local Path: $LOCAL_PUBLISH_DIR" echo "Local Path: $LOCAL_PUBLISH_DIR"
echo "Remote Path: $REMOTE_DEPLOY_PATH" echo "Remote Path: $REMOTE_DEPLOY_PATH"
echo "Backup Path: $REMOTE_BACKUP_PATH"
echo "Service: $SERVICE_NAME"
echo "Public URL: http://178.104.200.7/quant/"
echo "═══════════════════════════════════════════════════════════════" echo "═══════════════════════════════════════════════════════════════"
echo "" echo ""
@@ -33,6 +40,7 @@ ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'ENVCHECK'
echo "✓ SSH 연결 성공" echo "✓ SSH 연결 성공"
echo "" echo ""
echo "시스템 정보:" echo "시스템 정보:"
hostname
uname -a uname -a
echo "" echo ""
@@ -41,25 +49,25 @@ df -h | grep -E "^/dev|Filesystem|/$"
echo "" echo ""
echo "서비스 상태:" echo "서비스 상태:"
sudo systemctl status nginx --no-pager 2>/dev/null | grep -E "Active:|Loaded:" || echo "⚠️ nginx 상태 확인 필요" sudo systemctl status "$SERVICE_NAME" --no-pager 2>/dev/null | grep -E "Active:|Loaded:" || echo "⚠️ 서비스 상태 확인 필요"
echo "" echo ""
echo "웹 서버 디렉토리:" echo "배포 디렉토리:"
if [ -d /var/www/quant/publish ]; then if [ -d "/home/kjh2064/quantengine_active" ]; then
echo "✓ /var/www/quant/publish 존재" echo "✓ /home/kjh2064/quantengine_active 존재"
ls -lh /var/www/quant/publish | head -5 ls -lh /home/kjh2064/quantengine_active | head -5
echo "..." echo "..."
else else
echo "✗ /var/www/quant/publish 없음 (첫 배포)" echo "✗ /home/kjh2064/quantengine_active 없음 (첫 배포)"
fi fi
echo "" echo ""
echo "웹 서버 권한:" echo "Nginx 포트 확인:"
ls -ld /var/www/quant 2>/dev/null || echo "⚠️ /var/www/quant 없음" sudo netstat -tuln 2>/dev/null | grep ":80\|:443" || echo "⚠️ 포트 확인 필요"
echo "" echo ""
echo "Nginx 포트 확인:" echo "Nginx 설정:"
sudo netstat -tuln 2>/dev/null | grep :80 || echo "⚠️ 포트 80 확인 필요" cat /etc/nginx/sites-available/gitea-ip.conf | grep -A 5 "location /quant" || echo "⚠️ Nginx 설정 확인 필요"
ENVCHECK ENVCHECK
echo "" echo ""
@@ -105,20 +113,27 @@ fi
echo "" echo ""
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
# Step 4: 백업 생성 # Step 4: 서비스 중지 및 백업 생성
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
echo "💾 Step 3: 백업 생성..." echo "💾 Step 3: 서비스 중지 및 백업 생성..."
ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'BACKUP' ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'BACKUP'
set -e set -e
BACKUP_DIR="/var/www/quant_backup" SERVICE_NAME="quantengine"
BACKUP_NAME="quant_backup_$(date +%Y%m%d_%H%M%S)" DEPLOY_PATH="/home/kjh2064/quantengine_active"
BACKUP_DIR="/home/kjh2064/quantengine_backup"
BACKUP_NAME="quantengine_$(date +%Y%m%d_%H%M%S)"
if [ -d /var/www/quant/publish ]; then echo " 서비스 중지 중..."
sudo mkdir -p "$BACKUP_DIR" sudo systemctl stop "$SERVICE_NAME" 2>/dev/null || true
sudo cp -r /var/www/quant/publish "$BACKUP_DIR/$BACKUP_NAME" sleep 2
echo " ✓ 서비스 중지"
mkdir -p "$BACKUP_DIR"
if [ -d "$DEPLOY_PATH" ]; then
cp -r "$DEPLOY_PATH" "$BACKUP_DIR/$BACKUP_NAME"
echo "✓ 백업 생성: $BACKUP_DIR/$BACKUP_NAME" echo "✓ 백업 생성: $BACKUP_DIR/$BACKUP_NAME"
# 최근 5개만 유지 # 최근 5개만 유지
@@ -126,12 +141,13 @@ if [ -d /var/www/quant/publish ]; then
if [ "$BACKUP_COUNT" -gt 5 ]; then if [ "$BACKUP_COUNT" -gt 5 ]; then
OLD_BACKUPS=$(ls -1t "$BACKUP_DIR" | tail -n +6) OLD_BACKUPS=$(ls -1t "$BACKUP_DIR" | tail -n +6)
for backup in $OLD_BACKUPS; do for backup in $OLD_BACKUPS; do
sudo rm -rf "$BACKUP_DIR/$backup" rm -rf "$BACKUP_DIR/$backup"
echo "🧹 오래된 백업 삭제: $backup" echo "🧹 오래된 백업 삭제: $backup"
done done
fi fi
else else
echo "⚠️ 기존 배포 없음 (첫 배포)" echo "⚠️ 기존 배포 없음 (첫 배포)"
mkdir -p "$DEPLOY_PATH"
fi fi
BACKUP BACKUP
@@ -146,7 +162,7 @@ echo "📤 Step 4: 파일 전송 (rsync)..."
rsync -avz --delete \ rsync -avz --delete \
--rsh="ssh -i $SSH_KEY" \ --rsh="ssh -i $SSH_KEY" \
"$LOCAL_PUBLISH_DIR/" \ "$LOCAL_PUBLISH_DIR/" \
"$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_DEPLOY_PATH/publish/" "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_DEPLOY_PATH/"
echo "✓ 파일 전송 완료" echo "✓ 파일 전송 완료"
echo "" echo ""
@@ -155,26 +171,31 @@ echo ""
# Step 6: 권한 설정 및 서비스 재시작 # Step 6: 권한 설정 및 서비스 재시작
# ═══════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════
echo "🔧 Step 5: 권한 설정 및 서비스 시작..." echo "🔧 Step 5: 파일 검증 및 서비스 시작..."
ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'FINALIZE' ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'FINALIZE'
set -e set -e
DEPLOY_PATH="/var/www/quant" SERVICE_NAME="quantengine"
DEPLOY_PATH="/home/kjh2064/quantengine_active"
echo " 권한 설정 중..." echo " 파일 검증 중..."
sudo chown -R www-data:www-data "$DEPLOY_PATH/publish" 2>/dev/null || true if [ -f "$DEPLOY_PATH/QuantEngine.Web.dll" ]; then
sudo chmod -R 755 "$DEPLOY_PATH/publish" 2>/dev/null || true echo " ✓ QuantEngine.Web.dll 확인됨"
echo " ✓ 권한 설정 완료"
echo " nginx 재시작 중..."
sudo systemctl restart nginx 2>/dev/null || echo " ⚠️ nginx 재시작 실패 (sudo 권한 확인)"
sleep 2
if sudo systemctl is-active --quiet nginx 2>/dev/null; then
echo " ✓ nginx 재시작 완료"
else else
echo " ⚠️ nginx 상태 확인 필요" echo " ❌ QuantEngine.Web.dll 없음 (배포 실패)"
exit 1
fi
echo " 서비스 시작 중..."
sudo systemctl start "$SERVICE_NAME" 2>/dev/null || echo " ⚠️ 서비스 시작 실패"
sleep 3
if sudo systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
echo " ✓ $SERVICE_NAME 시작 완료"
else
echo " ⚠️ 서비스 상태 확인"
sudo systemctl status "$SERVICE_NAME" || true
fi fi
FINALIZE FINALIZE
@@ -186,16 +207,16 @@ echo ""
echo "🧪 Step 6: 헬스 체크..." echo "🧪 Step 6: 헬스 체크..."
for i in {1..5}; do for i in {1..30}; do
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
http://$DEPLOY_HOST/quant/ 2>/dev/null || echo "000") "http://$DEPLOY_HOST/quant/" 2>/dev/null || echo "000")
if [ "$HTTP_CODE" = "200" ]; then if [ "$HTTP_CODE" = "200" ]; then
echo "✓ Health check PASS (HTTP 200)" echo "✓ Health check PASS (HTTP 200)"
break break
fi fi
echo " 시도 $i/5: HTTP $HTTP_CODE (대기 중...)" echo " 시도 $i/30: HTTP $HTTP_CODE (대기 중...)"
sleep 2 sleep 2
done done
@@ -210,17 +231,23 @@ echo "✅ 배포 완료!"
echo "═══════════════════════════════════════════════════════════════" echo "═══════════════════════════════════════════════════════════════"
echo "" echo ""
echo "📊 배포 정보:" echo "📊 배포 정보:"
echo " URL: http://$DEPLOY_HOST/quant/" echo " 공인 URL: http://$DEPLOY_HOST/quant/"
echo " 경로: $REMOTE_DEPLOY_PATH/publish" echo " 배포 경로: $REMOTE_DEPLOY_PATH"
echo " 크기: $PACKAGE_SIZE" echo " 백업 경로: $REMOTE_BACKUP_PATH"
echo " 서비스: $SERVICE_NAME"
echo " 패키지 크기: $PACKAGE_SIZE"
echo ""
echo "🌐 구조:"
echo " Nginx: reverse proxy /quant/ → localhost:5000"
echo " 설정: /etc/nginx/sites-available/gitea-ip.conf"
echo "" echo ""
echo "🔍 로그 확인:" echo "🔍 로그 확인:"
echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST 'sudo tail -50 /var/log/nginx/error.log'" echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST 'sudo journalctl -u $SERVICE_NAME -f'"
echo "" echo ""
echo "🔄 롤백 (필요시):" echo "🔄 롤백 (필요시):"
echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST << 'EOF'" echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST << 'EOF'"
echo " LATEST=\$(ls -t /var/www/quant_backup | head -1)" echo " LATEST=\$(ls -t $REMOTE_BACKUP_PATH | head -1)"
echo " sudo cp -r /var/www/quant_backup/\$LATEST/* /var/www/quant/publish/" echo " cp -r $REMOTE_BACKUP_PATH/\$LATEST/* $REMOTE_DEPLOY_PATH/"
echo " sudo systemctl restart nginx" echo " sudo systemctl restart $SERVICE_NAME"
echo " EOF" echo " EOF"
echo "" echo ""
+225
View File
@@ -0,0 +1,225 @@
#!/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 ""