#!/bin/bash # TaxBaik 배포 전 검증 스크립트 # 목적: 배포 대상 버전의 완전성과 안정성을 검증 # 실행: bash scripts/validate-deploy.sh set -e TARGET_PORT=${1:-5003} BASE_URL="http://127.0.0.1:$TARGET_PORT" MAX_RETRIES=10 RETRY_DELAY=3 TIMEOUT=60 echo "🔍 배포 전 검증 시작" echo "================================" echo "대상 포트: $TARGET_PORT" echo "Base URL: $BASE_URL" echo "" # 색상 정의 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 검증 결과 추적 VALIDATION_FAILED=0 # ============================================ # 1️⃣ 프로세스 확인 # ============================================ echo "1️⃣ 포트 $TARGET_PORT 프로세스 확인..." if ! netstat -tlnp 2>/dev/null | grep -q ":$TARGET_PORT "; then echo -e "${RED}❌ 포트 $TARGET_PORT에 프로세스가 없습니다${NC}" VALIDATION_FAILED=1 else PROCESS_INFO=$(netstat -tlnp 2>/dev/null | grep ":$TARGET_PORT " | awk '{print $NF}') echo -e "${GREEN}✅ 프로세스 실행 중: $PROCESS_INFO${NC}" fi echo "" # ============================================ # 2️⃣ 헬스 체크 (재시도 포함) # ============================================ echo "2️⃣ 헬스 체크: $BASE_URL/healthz" HEALTH_OK=0 for i in $(seq 1 $MAX_RETRIES); do echo -n " 시도 $i/$MAX_RETRIES... " if RESPONSE=$(curl -sf --max-time 5 "$BASE_URL/healthz" 2>/dev/null); then if echo "$RESPONSE" | grep -q "Healthy"; then echo -e "${GREEN}✅ Healthy${NC}" HEALTH_OK=1 break fi fi echo -e "${YELLOW}대기 중${NC}" sleep $RETRY_DELAY done if [ $HEALTH_OK -eq 0 ]; then echo -e "${RED}❌ 헬스 체크 실패${NC}" VALIDATION_FAILED=1 fi echo "" # ============================================ # 3️⃣ 필수 API 엔드포인트 검증 # ============================================ echo "3️⃣ 필수 API 엔드포인트 검증..." declare -a ENDPOINTS=( "/api/auth/login:POST" "/api/admin-dashboard/summary:GET" "/api/blog:GET" "/api/inquiry:GET" ) for ENDPOINT_DEF in "${ENDPOINTS[@]}"; do IFS=':' read -r ENDPOINT METHOD <<< "$ENDPOINT_DEF" echo -n " $METHOD $ENDPOINT... " if [ "$METHOD" = "GET" ]; then HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$BASE_URL$ENDPOINT" 2>/dev/null || echo "000") else HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -X $METHOD "$BASE_URL$ENDPOINT" 2>/dev/null || echo "000") fi # GET: 200/404 허용 (리소스 없을 수 있음) # POST: 200/400/401/405 허용 VALID=0 case $HTTP_CODE in 200|400|401|404|405) VALID=1 ;; esac if [ $VALID -eq 1 ]; then echo -e "${GREEN}✅ ($HTTP_CODE)${NC}" else echo -e "${RED}❌ ($HTTP_CODE)${NC}" VALIDATION_FAILED=1 fi done echo "" # ============================================ # 4️⃣ 데이터베이스 연결 확인 # ============================================ echo "4️⃣ 데이터베이스 연결 확인..." # 간단한 API 호출로 DB 연결 검증 if curl -sf --max-time 5 "$BASE_URL/api/blog?limit=1" > /dev/null 2>&1; then echo -e "${GREEN}✅ 데이터베이스 연결 정상${NC}" else echo -e "${RED}❌ 데이터베이스 연결 실패${NC}" VALIDATION_FAILED=1 fi echo "" # ============================================ # 5️⃣ 로그 확인 (오류 없음) # ============================================ echo "5️⃣ 애플리케이션 로그 확인..." # 운영 서버의 배포 로그에서 FATAL, ERROR 확인 DEPLOY_LOG_DIR="/home/kjh2064/deployments" if [ -d "$DEPLOY_LOG_DIR" ]; then LATEST_LOG=$(find "$DEPLOY_LOG_DIR" -name "web_*.log" -type f 2>/dev/null | sort -r | head -1) if [ -n "$LATEST_LOG" ]; then if tail -100 "$LATEST_LOG" 2>/dev/null | grep -i "fatal\|exception\|error" | grep -v "INFO\|WARN" > /dev/null; then echo -e "${RED}❌ 로그에 오류가 있습니다${NC}" echo " 마지막 오류:" tail -100 "$LATEST_LOG" 2>/dev/null | grep -i "fatal\|exception\|error" | grep -v "INFO\|WARN" | tail -3 VALIDATION_FAILED=1 else echo -e "${GREEN}✅ 로그 정상 (오류 없음)${NC}" fi fi else echo -e "${YELLOW}⚠️ 로그 디렉토리 없음 (로컬 테스트 환경)${NC}" fi echo "" # ============================================ # 6️⃣ 메모리/CPU 사용량 확인 # ============================================ echo "6️⃣ 리소스 사용량 확인..." if command -v ps > /dev/null; then PS_OUTPUT=$(ps aux | grep -E "dotnet.*$TARGET_PORT" | grep -v grep) if [ -n "$PS_OUTPUT" ]; then # CPU%, MEM% 확인 CPU_USAGE=$(echo "$PS_OUTPUT" | awk '{print $3}') MEM_USAGE=$(echo "$PS_OUTPUT" | awk '{print $4}') echo " CPU 사용률: $CPU_USAGE%" echo " 메모리 사용률: $MEM_USAGE%" # 경고: CPU > 50% 또는 메모리 > 30% CPU_THRESHOLD=50 MEM_THRESHOLD=30 CPU_CHECK=$(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc 2>/dev/null || echo 0) MEM_CHECK=$(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc 2>/dev/null || echo 0) if [ "$CPU_CHECK" = "1" ] || [ "$MEM_CHECK" = "1" ]; then echo -e "${YELLOW}⚠️ 리소스 사용량이 높습니다 (경고)${NC}" # 경고만 (배포는 계속) else echo -e "${GREEN}✅ 리소스 사용량 정상${NC}" fi fi fi echo "" # ============================================ # 최종 결과 # ============================================ echo "================================" if [ $VALIDATION_FAILED -eq 0 ]; then echo -e "${GREEN}✅ 배포 전 검증 성공!${NC}" echo " 배포를 진행할 수 있습니다." exit 0 else echo -e "${RED}❌ 배포 전 검증 실패!${NC}" echo " 배포를 중단합니다." echo "" echo "확인 사항:" echo " 1. 앱이 올바르게 시작되었는지 확인" echo " 2. 데이터베이스 연결 확인" echo " 3. 로그에서 오류 메시지 확인" echo " 4. Nginx 설정 확인" exit 1 fi