Files
QuantEngineByItz/docs/archive/DEPLOYMENT_SSH_GUIDE.md
kjh2064 15c7971018
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (pull_request) Failing after 4s
Quant Engine CI/CD Pipeline / validate-core (pull_request) Failing after 2m15s
Quant Engine CI/CD Pipeline / validate-ui-and-storage (pull_request) Has been skipped
chore: root 경로의 미사용/과거 문서 및 스크립트를 docs/ 하위로 정리 격리
2026-06-26 11:35:42 +09:00

9.8 KiB

🔐 SSH 배포 가이드 (v9)

목표: SSH로 원격 서버에 직접 접속하여 배포
환경: hz-prod-01 (공인 IP 178.104.200.7 / 내부 IP 172.17.0.1)


📋 사전 준비

1. SSH 키 설정 (최초 1회)

1.1 로컬에서 SSH 키 생성

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

1.2 공개 키를 원격 서버에 등록

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

1.3 SSH 연결 테스트

ssh -i ~/.ssh/id_ed25519 kjh2064@178.104.200.7 "echo '✅ 연결 성공'"

🔍 Step 1: 환경 파악

원격 서버 정보 확인

ssh kjh2064@178.104.200.7 << 'EOF'

# 1. 시스템 정보
echo "=== 시스템 정보 ==="
hostname
uname -a
lsb_release -a

# 2. 배포 경로
echo -e "\n=== 배포 경로 ==="
ls -la /home/kjh2064/quantengine_active/ || echo "아직 없음 (첫 배포)"
ls -la /home/kjh2064/quantengine_backup/

# 3. 서비스 상태
echo -e "\n=== quantengine 서비스 ==="
sudo systemctl status quantengine --no-pager

# 4. Nginx 설정
echo -e "\n=== Nginx /quant 설정 ==="
cat /etc/nginx/sites-available/gitea-ip.conf | grep -A 10 "location /quant"

# 5. 포트 상태
echo -e "\n=== 포트 상태 ==="
sudo netstat -tuln | grep -E ":80|:443|:5000"

# 6. 디스크 상태
echo -e "\n=== 디스크 ==="
df -h

EOF

예상 환경

✓ Linux (Ubuntu 20.04+)
✓ nginx 1.28.3 (reverse proxy)
✓ /home/kjh2064/quantengine_active/ 배포 경로
✓ quantengine systemd 서비스
✓ 포트 5000에서 .NET 앱 실행
✓ sudo 권한 (quantengine 서비스 제어)

🏗️ 배포 아키텍처

┌────────────────────────────────────────────────────┐
│         사용자 (외부 인터넷)                         │
│      http://178.104.200.7/quant/                    │
└─────────────────────┬────────────────────────────────┘
                      │ 공인 IP (포트 80)
┌─────────────────────▼────────────────────────────────┐
│          Nginx (reverse proxy)                       │
│   /etc/nginx/sites-available/gitea-ip.conf          │
│   location /quant/ → proxy_pass http://127.0.0.1:5000/
└─────────────────────┬────────────────────────────────┘
                      │ localhost:5000
┌─────────────────────▼────────────────────────────────┐
│     quantengine (systemd 서비스)                    │
│   /home/kjh2064/quantengine_active/                │
│   QuantEngine.Web.dll (실행 중)                     │
└────────────────────────────────────────────────────┘

📦 Step 2: Release 빌드

# 로컬 개발 머신에서 실행
cd /c/Temp/data_feed

# Release 빌드
dotnet publish -c Release \
  -o src/dotnet/QuantEngine.Web/publish

# 결과 확인
ls -lh src/dotnet/QuantEngine.Web/publish/
du -sh src/dotnet/QuantEngine.Web/publish/

🚀 Step 3: 배포 방법

방법 1: 자동 배포 스크립트 (권장)

# 스크립트에 실행 권한 부여
chmod +x deploy-production.sh

# 배포 실행
./deploy-production.sh
# 또는
./deploy-manual.sh 178.104.200.7

스크립트가 자동으로:

  • ✓ SSH 연결 확인
  • ✓ 원격 환경 파악
  • ✓ 서비스 중지
  • ✓ 백업 생성
  • ✓ 파일 전송 (rsync)
  • ✓ 파일 검증
  • ✓ 서비스 시작
  • ✓ 헬스 체크

방법 2: 수동 배포 (단계별)

Step 2-1: SSH 접속

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

Step 2-2: 서비스 중지 및 백업

# 원격 서버에서 실행:
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)"

# 서비스 중지
sudo systemctl stop $SERVICE_NAME
sleep 2
echo "✓ 서비스 중지"

# 백업 생성
mkdir -p $BACKUP_PATH
if [ -d $DEPLOY_PATH ]; then
  cp -r $DEPLOY_PATH "$BACKUP_PATH/$BACKUP_NAME"
  echo "✓ 백업: $BACKUP_PATH/$BACKUP_NAME"
else
  mkdir -p $DEPLOY_PATH
  echo "⚠️ 첫 배포"
fi

Step 2-3: SSH 종료

exit

Step 2-4: 파일 전송 (로컬에서)

rsync -avz --delete \
  -e "ssh -i ~/.ssh/id_ed25519" \
  src/dotnet/QuantEngine.Web/publish/ \
  kjh2064@178.104.200.7:/home/kjh2064/quantengine_active/

Step 2-5: 서비스 시작

ssh -i ~/.ssh/id_ed25519 kjh2064@178.104.200.7 << 'EOF'

SERVICE_NAME="quantengine"
DEPLOY_PATH="/home/kjh2064/quantengine_active"

# 파일 검증
if [ -f $DEPLOY_PATH/QuantEngine.Web.dll ]; then
  echo "✓ 파일 확인됨"
else
  echo "❌ 파일 없음"
  exit 1
fi

# 서비스 시작
sudo systemctl start $SERVICE_NAME
sleep 3

# 상태 확인
if sudo systemctl is-active --quiet $SERVICE_NAME; then
  echo "✓ 서비스 시작됨"
else
  echo "❌ 서비스 시작 실패"
  exit 1
fi

EOF

Step 4: 배포 검증

HTTP 상태 확인

# 공인 IP로 접근 (외부 사용자 기준)
curl -I http://178.104.200.7/quant/
# 기대: HTTP/1.1 200 OK

# localhost:5000 직접 확인 (서버에서)
ssh kjh2064@178.104.200.7 'curl -I http://127.0.0.1:5000/'
# 기대: HTTP/1.1 200 OK

MudBlazor 리소스 확인

curl -s http://178.104.200.7/quant/ | grep -c "MudBlazor"
# 기대: > 0

페이지 제목 확인

curl -s http://178.104.200.7/quant/ | grep -o "<title>.*</title>"
# 기대: <title>Quant Engine - Dashboard</title>

로그 확인

# 서비스 로그
ssh kjh2064@178.104.200.7 'sudo journalctl -u quantengine -n 50'

# Nginx 에러 로그
ssh kjh2064@178.104.200.7 'sudo tail -f /var/log/nginx/error.log'

# 실시간 모니터링
ssh kjh2064@178.104.200.7 'sudo journalctl -u quantengine -f'

브라우저 테스트

http://178.104.200.7/quant/

🔄 롤백 (배포 실패 시)

자동 롤백 스크립트

ssh kjh2064@178.104.200.7 << 'EOF'
set -e

SERVICE_NAME="quantengine"
DEPLOY_PATH="/home/kjh2064/quantengine_active"
BACKUP_PATH="/home/kjh2064/quantengine_backup"

echo "🔄 최신 백업 찾는 중..."
LATEST=$(ls -t $BACKUP_PATH | head -1)
echo "롤백 대상: $LATEST"

# 서비스 중지
sudo systemctl stop $SERVICE_NAME
sleep 2

# 백업 복원
cp -r "$BACKUP_PATH/$LATEST"/* "$DEPLOY_PATH/"
echo "✓ 백업 복원 완료"

# 서비스 시작
sudo systemctl start $SERVICE_NAME
sleep 3

# 확인
if sudo systemctl is-active --quiet $SERVICE_NAME; then
  echo "✅ 롤백 완료"
else
  echo "❌ 롤백 실패"
  exit 1
fi
EOF

📊 배포 체크리스트

배포 전

[ ] SSH 키 설정 완료 (~/.ssh/id_ed25519)
[ ] SSH 연결 테스트 성공
[ ] Release 빌드 완료 (24MB+)
[ ] 배포 스크립트 준비

배포 중

[ ] 환경 파악 완료
[ ] 서비스 중지 확인
[ ] 백업 생성 확인
[ ] 파일 전송 완료 (rsync)
[ ] 파일 검증 완료
[ ] 서비스 시작 완료

배포 후

[ ] HTTP 200 OK 확인
[ ] localhost:5000 응답 확인
[ ] MudBlazor 리소스 로드됨
[ ] Nginx 에러 로그 확인
[ ] 브라우저 접속 테스트
[ ] 페이지 로드 시간 < 2s

🆘 문제 해결

SSH 연결 타임아웃

# 확인:
1. IP 주소: 178.104.200.7 또는 172.17.0.1?
2. SSH 포트: 22 (기본값)
3. 방화벽 규칙
4. 공개 키 등록 확인

# 해결:
ssh-copy-id -i ~/.ssh/id_ed25519.pub kjh2064@178.104.200.7

서비스 시작 실패

# 로그 확인
ssh kjh2064@178.104.200.7 'sudo journalctl -u quantengine -n 50'

# 설정 확인
ssh kjh2064@178.104.200.7 'cat /etc/systemd/system/quantengine.service'

# 파일 검증
ssh kjh2064@178.104.200.7 'ls -la /home/kjh2064/quantengine_active/'

Nginx 프록시 오류

# Nginx 설정 테스트
ssh kjh2064@178.104.200.7 'sudo nginx -t'

# 설정 파일 확인
ssh kjh2064@178.104.200.7 'cat /etc/nginx/sites-available/gitea-ip.conf'

# 포트 확인
ssh kjh2064@178.104.200.7 'sudo netstat -tuln | grep 5000'

파일 권한 문제

# 현재 권한 확인
ssh kjh2064@178.104.200.7 'ls -la /home/kjh2064/quantengine_active/'

# 권한 설정 (필요시)
ssh kjh2064@178.104.200.7 'chmod +x /home/kjh2064/quantengine_active/QuantEngine.Web.dll'

📚 관련 파일

배포 스크립트:
├── deploy-production.sh (권장)
└── deploy-manual.sh (대화형)

배포 문서:
├── DEPLOYMENT_GUIDE.md (전체)
├── DEPLOYMENT_STEPS.md (단계별)
├── DEPLOYMENT_SSH_GUIDE.md (이 파일)
└── DEPLOYMENT_CHECKLIST.md (체크리스트)

CI/CD:
├── .gitea/workflows/deploy-prod.yml
└── CI_CD_PIPELINE.md

환경:
└── ENVIRONMENT_DIAGNOSIS.md

빠른 배포 명령어

한 번에 배포

chmod +x deploy-production.sh && ./deploy-production.sh

내부 IP 사용 (선택)

./deploy-manual.sh 172.17.0.1

공인 IP 사용 (권장)

./deploy-manual.sh 178.104.200.7

상태 확인

ssh kjh2064@178.104.200.7 'sudo systemctl status quantengine'

로그 모니터링

ssh kjh2064@178.104.200.7 'sudo journalctl -u quantengine -f'

배포 준비 완료! 🚀

deploy-production.sh 또는 deploy-manual.sh 스크립트를 실행하거나, 위의 수동 단계를 따라 배포하세요.