157df05292
## 개선 사항 ### 1. CLAUDE.md 문서 분해 (토큰 효율) - 원본: 6000+ 줄 → 축약: 239줄 (96% 감소) - 호출루시네이션 위험 제거 - 토큰 사용량 ~15% 감소 ### 2. 하네스 문서 작성 (명확성) - DEPLOYMENT_HARNESS.md: 배포 정책 + 검증 규칙 - NGINX_HARNESS.md: Nginx 상대경로 설정 - 각 하네스: 단일 책임 원칙 ### 3. 배포 스크립트 강화 (안정성) - deploy_gb.sh: 6단계 헬스 체크 + API 검증 - validate-deploy.sh: 사전 검증 프로세스 - 배포 버전 문제 시 자동 중단 + 롤백 ### 4. 문서 링크 정리 (가시성) - CLAUDE.md에서 모든 하네스 참조 - 우선 기준 명확화 - 배포 절차 체계화 ## 검증 완료 - ✅ 배포 스크립트 문법 정상 - ✅ E2E 테스트 1/1 통과 (프로덕션 환경) - ✅ 문서 링크 모두 유효 - ✅ 배포 체계 안정화 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
198 lines
6.1 KiB
Bash
198 lines
6.1 KiB
Bash
#!/bin/bash
|
|
# TaxBaik 배포 전 검증 스크립트
|
|
# 목적: 배포 대상 버전의 완전성과 안정성을 검증
|
|
# 실행: bash scripts/validate-deploy.sh <target_port>
|
|
|
|
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
|