# CI/CD 배포 트러블슈팅 가이드 **작성일**: 2026-07-11 **버전**: 1.0 **대상**: QuantEngine 배포 담당자 --- ## 1. 배포 실패 진단 ### 1.1 Pre-Deployment 실패 **증상**: 배포가 시작되지 않음 ``` [ERR] ERROR: SSH key not found [ERR] ERROR: Build artifact not found [ERR] ERROR: DB password secret not configured ``` **해결방법**: | 오류 | 원인 | 해결책 | |------|------|--------| | SSH key not found | Gitea Actions에서 SSH 키 미설정 | Gitea Settings > Repository Secrets에서 SSH_KEY 추가 | | Build artifact missing | 이전 단계(Build) 실패 | merge-to-main.yml의 Stage 4 로그 확인 | | DB password not configured | Gitea Secrets 미설정 | Gitea Settings > Repository Secrets에서 QUANTENGINE_DB_PASSWORD 추가 | | Config files missing | deploy/ 디렉토리 미포함 | 소스 코드의 `deploy/` 폴더 확인 | **빠른 확인**: ```bash # 로컬에서 필수 파일 확인 ls -la ./deploy/ ls -la deploy_gb.sh file quantengine.tar.gz # 파일 크기 1MB 이상 확인 ``` --- ### 1.2 배포 실패 (Extract Stage) **증상**: ``` [ERR] FATAL: Failed to extract artifact [ERR] tar: (standard input): gzip: stdin: unexpected end of file ``` **원인 분석**: - 빌드 아티팩트 손상 - 부분 다운로드된 파일 - 압축 형식 오류 **해결책**: 1. **빌드 아티팩트 재생성**: ```bash # 로컬에서 강제 재빌드 dotnet clean src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj dotnet build -c Release ``` 2. **tar 파일 검증**: ```bash # 정상 tar 파일인지 확인 tar -tzf quantengine.tar.gz | head -20 # 파일 크기 확인 (최소 1MB 이상) ls -lh quantengine.tar.gz ``` 3. **재배포 트리거**: ```bash # 새 커밋 생성 또는 manual dispatch git commit --allow-empty -m "rebuild: Force redeployment" git push origin main ``` --- ### 1.3 배포 실패 (Structure Normalization) **증상**: ``` [ERR] FATAL: QuantEngine.Web.dll not found in deployment ``` **원인**: - net10.0 구조 정규화 실패 - DLL 파일이 중첩된 폴더에 있음 **해결책**: 1. **배포 디렉토리 구조 확인**: ```bash ls -lh /home/kjh2064/deployments/quantengine_*/ ``` 2. **수동 구조 정리** (긴급 복구): ```bash # 가장 최근 배포 확인 LATEST=$(ls -dt /home/kjh2064/deployments/quantengine_* | head -1) # net10.0 아래 파일들 이동 mv $LATEST/net10.0/* $LATEST/ rmdir $LATEST/net10.0 # 서비스 재시작 systemctl restart quantengine ``` --- ### 1.4 헬스 체크 실패 **증상**: ``` [ERR] FAILED: Health check did not pass after 5 attempts [ERR] Service not responding on http://127.0.0.1:5000/ ``` **진단**: ```bash # 1. 서비스 상태 확인 systemctl status quantengine.service # 2. 포트 점유 확인 lsof -i :5000 || ss -tlnp | grep 5000 # 3. 서비스 로그 확인 journalctl -u quantengine.service -n 50 # 4. DB 연결 테스트 PGPASSWORD='pvuIp8fWNj+oWfZtciw43GzJ4yU0vwKf' \ psql -h 127.0.0.1 -U quantengine_app -d quantenginedb -c "SELECT 1;" # 5. 포트 수동 테스트 curl -v http://127.0.0.1:5000/ ``` **공통 해결책**: | 증상 | 원인 | 해결책 | |------|------|--------| | Connection refused | 서비스 시작 안 됨 | `systemctl restart quantengine` | | Address already in use | 이전 프로세스 남음 | `pkill -f "dotnet.*QuantEngine"` | | Database error | DB 연결 실패 | appsettings.Production.json 비밀번호 확인 | | Timeout | 느린 시작 | HEALTH_CHECK_RETRIES 증가 | --- ### 1.5 자동 롤백 실패 **증상**: ``` [ERR] CRITICAL: Rollback failed - previous deployment not found ``` **원인**: - 이전 배포가 삭제됨 - 배포 디렉토리 정리로 인한 손실 **예방**: ```bash # 배포 히스토리 확인 ls -ldt /home/kjh2064/deployments/quantengine_* | head -10 # 수동 롤백 (긴급) PREV_DEPLOY="/home/kjh2064/deployments/quantengine_YYYYMMDD_HHMMSS" ln -sfn $PREV_DEPLOY /home/kjh2064/quantengine_active systemctl restart quantengine ``` --- ## 2. 배포 수동 관리 ### 2.1 수동 배포 트리거 ```bash # Gitea Actions에서 Manual Dispatch # 또는 CI/CD에서 commit → main 푸시 git commit --allow-empty -m "deploy: Manual trigger" git push origin main ``` ### 2.2 현재 배포 상태 확인 ```bash # 활성 배포 확인 readlink /home/kjh2064/quantengine_active # 배포 디렉토리 목록 ls -lht /home/kjh2064/deployments/quantengine_* | head -5 # 서비스 상태 systemctl status quantengine.service # 최근 로그 journalctl -u quantengine.service -f ``` ### 2.3 즉시 롤백 ```bash # 1. 이전 배포 선택 DEPLOYMENTS=$(ls -dt /home/kjh2064/deployments/quantengine_*) PREV=$(echo "$DEPLOYMENTS" | head -2 | tail -1) # 2. 롤백 실행 ln -sfn $PREV /home/kjh2064/quantengine_active # 3. 서비스 재시작 systemctl restart quantengine # 4. 확인 systemctl status quantengine.service curl http://127.0.0.1:5000/ ``` --- ## 3. 성능 최적화 ### 3.1 배포 시간 단축 ```bash # 배포 캐시 검증 du -sh /home/kjh2064/deployments/ # 오래된 배포 수동 정리 (유지: 3개) ls -dt /home/kjh2064/deployments/quantengine_* | tail -n +4 | xargs rm -rf ``` ### 3.2 헬스 체크 타임아웃 조정 `.gitea/workflows/deploy-prod.yml`에서: ```yaml env: HEALTH_CHECK_RETRIES: "5" # 재시도 횟수 HEALTH_CHECK_DELAY: "3" # 재시도 간격 (초) ``` --- ## 4. 모니터링 & 알림 ### 4.1 Telegram 알림 설정 ```bash # Gitea Settings > Repository Secrets에서 설정 TELEGRAM_BOT_TOKEN= TELEGRAM_CHAT_ID= ``` ### 4.2 배포 로그 위치 ```bash # 최근 배포 로그 journalctl -u quantengine.service -n 100 # 배포 정보 확인 cat /home/kjh2064/deployments/quantengine_*/(.deployment_info) ``` --- ## 5. 자주 묻는 질문 (FAQ) **Q: 배포는 되었는데 변경사항이 반영되지 않음** ```bash # 1. 캐시 확인 curl -H "Cache-Control: no-cache" https://quant.taxbaik.com/ # 2. 서비스 재시작 systemctl restart quantengine # 3. 브라우저 캐시 삭제 후 재접속 ``` **Q: "appsettings.Production.json not found" 오류** ```bash # 파일이 자동 생성되므로 정상 # 만약 없다면: cat > /home/kjh2064/quantengine_active/appsettings.Production.json << 'EOF' { "ConnectionStrings": { "DefaultConnection": "Host=127.0.0.1;Database=quantenginedb;Username=quantengine_app;Password=;Search Path=quantengine;" } } EOF systemctl restart quantengine ``` **Q: 데이터베이스 연결이 계속 실패** ```bash # 비밀번호 확인 grep "Password=" /home/kjh2064/quantengine_active/appsettings.Production.json # DB 직접 테스트 PGPASSWORD='pvuIp8fWNj+oWfZtciw43GzJ4yU0vwKf' \ psql -h 127.0.0.1 -U quantengine_app -d quantenginedb -c "SELECT version();" ``` --- ## 6. 연락처 & 지원 - **배포 담당**: kjh2064 - **긴급 롤백**: systemctl restart quantengine - **로그 위치**: /var/log/journalctl, /home/kjh2064/deployments/*/logs/ - **모니터링**: https://quant.taxbaik.com/Admin/Monitoring --- **마지막 업데이트**: 2026-07-11 **다음 업데이트 예정**: 버그 수정 후