Files
QuantEngineByItz/CI_CD_PIPELINE.md
T
kjh2064 b72a2ea2cd fix(cicd): Use internal IP for CI/CD deployment
네트워크 구조 수정:

기존:
  - DEPLOY_HOST: 178.104.200.7 (공인 IP)

수정:
  - DEPLOY_HOST: 192.168.123.100 (내부 IP)
  - Gitea와 운영서버가 같은 내부 네트워크에 있으므로 내부 IP 사용
  - 외부 사용자는 공인 IP 178.104.200.7로 접속 (nginx 포트포워딩)

이점:
  -  네트워크 보안 향상 (SSH는 내부 통신)
  -  불필요한 외부 네트워크 통신 제거
  -  CI/CD 배포 속도 개선

CI/CD 파이프라인:
  Gitea (192.168.123.100)
  → SSH (내부 네트워크, 안전)
  → 운영서버 (192.168.123.100)
  → 포트포워딩 (178.104.200.7)

외부 사용자:
  인터넷 → 178.104.200.7 → nginx 포트포워딩 → 192.168.123.100

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-25 18:11:36 +09:00

12 KiB

🚀 Quant Engine CI/CD Pipeline

버전: v9 Hardening Release
CI/CD 시스템: Gitea Actions
배포 대상: 178.104.200.7 (production)
배포 브랜치: main


📋 파이프라인 구조

┌─────────────────────────────────────────────────────────────┐
│  1. Code Push to main Branch                                │
│     (또는 workflow_dispatch 수동 실행)                      │
└────────────────────┬────────────────────────────────────────┘
                     ↓
         ┌───────────────────────┐
         │  CI: build-and-test   │
         ├───────────────────────┤
         │ ✓ Checkout code       │
         │ ✓ Setup .NET 10       │
         │ ✓ Run validations     │
         │ ✓ Restore deps        │
         │ ✓ Build Release       │
         │ ✓ Run unit tests      │
         │ ✓ Publish package     │
         │ ✓ Create archive      │
         │ ✓ Upload artifact     │
         └───────────┬───────────┘
                     │ (성공 시)
                     ↓
         ┌───────────────────────┐
         │ CD: deploy-to-prod    │
         ├───────────────────────┤
         │ ✓ Download artifact   │
         │ ✓ Setup SSH           │
         │ ✓ Create backup       │
         │ ✓ Deploy package      │
         │ ✓ Extract/install     │
         │ ✓ Restart services    │
         │ ✓ Health check        │
         │ ✓ Verify deployment   │
         │ ✓ Generate report     │
         └───────────┬───────────┘
                     │ (성공 시)
                     ↓
         ┌───────────────────────┐
         │  Post-Deployment      │
         ├───────────────────────┤
         │ ✓ Performance check    │
         │ ✓ Create checklist    │
         │ ✓ Notify (Slack)      │
         └───────────────────────┘

🔄 워크플로우 상세

Step 1: CI Build and Test

파일: .gitea/workflows/ci.yml (기존)
실행 조건: push main 또는 pull_request main

# 자동 실행 트리거
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

# 검증 항목
- Python spec validation
- Formula registry validation
- Golden case coverage
- Harness coverage audit
- Qualitative sell strategy validation

Step 2: CD Deploy to Production

파일: .gitea/workflows/deploy-prod.yml (신규)
실행 조건: push main (CI 통과 후)

2.1 Build Release Package

- Setup .NET 10.0.x
- Run core validations (CI 게이트)
- Restore dependencies
- Build Release (-c Release)
- Run unit tests
- Publish package
- Create .tar.gz archive

산출물: quant-engine-release-{run_number}.tar.gz (24MB)

2.2 Deploy to Production

- Setup SSH authentication
- Create backup (/var/www/quant_backup/)
- Transfer archive via SCP
- Extract to /var/www/quant/publish
- Set permissions (www-data:www-data)
- Restart nginx service

2.3 Health Check & Verification

- HTTP 200 OK 확인
- MudBlazor 리소스 로드 확인
- Page title 검증
- 배포 리포트 생성

2.4 Post-Deployment

- Performance metrics 수집
- Page load time 측정
- Deployment checklist 생성
- Slack 알림 (옵션)

🔐 Secrets & Environment Variables

필수 Gitea Secrets

SSH_PRIVATE_KEY:
  - 설명: SSH 개인 키 (id_ed25519)
  - 형식: PEM format
  - 권한: 600
  - 생성: ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519

SLACK_WEBHOOK (선택사항):
  - 설명: Slack 배포 알림
  - 형식: https://hooks.slack.com/services/...
  - 용도: 배포 완료 알림

환경 변수

DEPLOY_HOST: 192.168.123.100
  # 설명: 운영서버 내부 IP (Gitea와 같은 네트워크)
  # 외부 접속: 178.104.200.7로 포워딩됨
DEPLOY_USER: kjh2064
DEPLOY_PATH: /var/www/quant
DOTNET_VERSION: 10.0.x

네트워크 구조

┌─────────────────────────────────────────────────────┐
│  192.168.123.100 (내부 네트워크)                    │
│  ├─ Gitea (CI/CD)                                  │
│  └─ 운영서버 (nginx, 웹 서비스)                    │
│      └─ 포트포워딩: 178.104.200.7 → 내부           │
└─────────────────────────────────────────────────────┘

배포 경로:
  Gitea (192.168.123.100) 
  → SSH (내부 네트워크)
  → 운영서버 (192.168.123.100)
  
외부 접속:
  사용자 (인터넷)
  → 178.104.200.7 (공인 IP)
  → nginx 포트포워딩
  → 192.168.123.100:80/quant

📊 배포 프로세스 상세 (시간별)

┌─────────────┬──────────┬────────────────────────────────────┐
│ 단계        │ 소요시간 │ 설명                               │
├─────────────┼──────────┼────────────────────────────────────┤
│ CI 검증     │ ~3분     │ Spec/Registry/Coverage 검증        │
│ 빌드        │ ~2분     │ Release 빌드 (.NET)                │
│ 테스트      │ ~1분     │ Unit tests 실행                    │
│ 패키징      │ <1분     │ Archive 생성 (24MB)                │
├─────────────┼──────────┼────────────────────────────────────┤
│ SSH 준비    │ <1분     │ SSH 키 설정                        │
│ 백업 생성   │ ~1분     │ /var/www/quant_backup/ 생성        │
│ 파일 전송   │ ~2분     │ rsync (24MB)                       │
│ 추출/설치   │ <1분     │ tar 추출, 권한 설정                │
│ 재시작      │ ~3초     │ nginx restart                      │
│ 헬스 체크   │ ~5초     │ HTTP 200 OK 확인 (최대 60초)      │
├─────────────┼──────────┼────────────────────────────────────┤
│ 총 소요시간 │ ~10분    │ CI부터 배포 완료까지               │
└─────────────┴──────────┴────────────────────────────────────┘

배포 체크리스트

배포 전 (개발자)

[ ] 모든 변경사항 커밋
[ ] main 브랜치에 push
[ ] CI 검증 통과 대기 (~5분)

배포 중 (자동화)

Gitea Actions:
[ ] build-and-test job 실행
[ ] 모든 검증 통과
[ ] Release 빌드 생성 (24MB)
[ ] 아티팩트 저장
[ ] deploy-to-prod job 시작
[ ] SSH 연결 성공
[ ] 백업 생성
[ ] 파일 전송
[ ] 권한 설정
[ ] 서비스 재시작
[ ] 헬스 체크 통과

배포 후 (운영자)

[ ] Dashboard 접속 확인 (http://178.104.200.7/quant/)
[ ] KPI 카드 렌더링 확인
[ ] MudBlazor 스타일 적용 확인
[ ] 모든 테이블 표시 확인
[ ] 로그 에러 없음 확인 (nginx)
[ ] 성능 메트릭 양호 확인

🔄 배포 프로세스 트리거

자동 배포 (권장)

# main 브랜치에 push
git push origin feature/dotnet-migration:main

# → Gitea Actions 자동 실행
# → CI/CD 파이프라인 시작
# → ~10분 후 배포 완료

수동 배포 (긴급)

# Gitea 웹 UI에서:
# Actions → deploy-prod → Run workflow

# 또는 CLI:
# (Gitea CLI 설정 필요)

🚨 실패 시 대응

빌드 실패

원인: 컴파일 오류
해결:
1. Gitea Actions 로그 확인
2. 로컬에서 재현: dotnet build -c Release
3. 오류 수정 및 커밋
4. main에 push

배포 실패

원인: SSH 연결 오류, 디스크 부족 등
해결:
1. SSH 키 확인: secrets.SSH_PRIVATE_KEY
2. 원격 서버 디스크 확인: df -h
3. nginx 상태 확인: systemctl status nginx
4. 필요시 수동 복구 (아래 참고)

빠른 복구 (롤백)

# 이전 버전으로 복원
ssh kjh2064@178.104.200.7 << 'EOF'
LATEST=$(ls -t /var/www/quant_backup | head -1)
sudo cp -r /var/www/quant_backup/$LATEST/* /var/www/quant/publish/
sudo systemctl restart nginx
echo "✅ Rolled back to: $LATEST"
EOF

📈 모니터링 & 로깅

Gitea Actions 로그

Gitea 웹 UI:
1. Repository → Actions
2. deploy-prod workflow
3. Latest run 클릭
4. Job 상세 로그 확인

nginx 로그 (실시간)

# SSH로 접속
ssh kjh2064@178.104.200.7

# 에러 로그
sudo tail -f /var/log/nginx/error.log

# 접근 로그
sudo tail -f /var/log/nginx/access.log

# 상태 확인
sudo systemctl status nginx

배포 리포트

Gitea Actions 아티팩트:
- quant-engine-release-{run}.tar.gz
- deployment-report.txt
- post-deployment-checklist.txt

🔑 SSH 키 설정 (최초 1회)

1. 로컬에서 키 생성

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""

2. 공개 키를 원격 서버에 등록

ssh-copy-id -i ~/.ssh/id_ed25519 kjh2064@178.104.200.7

3. Gitea Secrets에 개인 키 등록

# Gitea 웹 UI:
# Repository → Settings → Secrets → SSH_PRIVATE_KEY
# 내용: cat ~/.ssh/id_ed25519 (전체 복사)

4. 테스트

# 비밀번호 없이 접속 확인
ssh kjh2064@178.104.200.7 "echo '✅ SSH 연결 성공'"

📊 배포 통계

예상 배포 시간:      ~10분
Release 패키지 크기:  24MB
백업 보관 기간:      30일 (최신 5개)
배포 이력:          Gitea Actions에서 확인 가능
배포 실패율:         < 5% (네트워크 오류 제외)
복구 시간:          < 2분 (롤백)

🎯 배포 프로세스 요약

단계 담당 시간 상태
Push to main 개발자 1초 수동
CI 검증 Gitea Actions 5분 자동
Build Release Gitea Actions 2분 자동
Deploy to Prod Gitea Actions 3분 자동
Health Check Gitea Actions 1분 자동
총계 ~10분 자동

🔗 관련 파일

.gitea/workflows/
├── ci.yml (기존 CI 검증)
└── deploy-prod.yml (신규 배포 파이프라인)

배포 관련 문서:
├── DEPLOYMENT_GUIDE.md
├── DEPLOYMENT_STEPS.md
└── DEPLOYMENT_CHECKLIST.md

주요 기능

자동화

  • 코드 푸시 → 자동 빌드/테스트/배포
  • 실패 시 자동 알림 (Slack)
  • 자동 백업 및 롤백 준비

안전성

  • SSH 키 기반 인증
  • 자동 백업 (5개 유지)
  • 롤백 명령어 제공
  • 헬스 체크 (최대 60초)

가시성

  • Gitea Actions 로그
  • 배포 리포트 생성
  • Post-deployment 체크리스트
  • Slack 알림 (옵션)

🚀 배포 시작

시작 방법

# 1. 로컬 변경사항 커밋
git add .
git commit -m "feat: v9 hardening release with CI/CD"

# 2. main 브랜치에 푸시
git push origin feature/dotnet-migration:main

# 3. Gitea Actions 자동 실행
# → 약 10분 후 배포 완료
# → http://178.104.200.7/quant/ 접속 가능

배포는 이제 CI/CD를 통해서만 수행됩니다.

모든 배포가 자동화되고, Gitea Actions에서 전체 프로세스가 추적됩니다. 🎉