diff --git a/DEPLOYMENT_SSH_GUIDE.md b/DEPLOYMENT_SSH_GUIDE.md new file mode 100644 index 0000000..3064b9c --- /dev/null +++ b/DEPLOYMENT_SSH_GUIDE.md @@ -0,0 +1,347 @@ +# πŸ” SSH 배포 κ°€μ΄λ“œ + +**λͺ©ν‘œ**: SSH둜 원격 μ„œλ²„μ— 직접 μ ‘μ†ν•˜μ—¬ ν™˜κ²½μ„ νŒŒμ•…ν•œ ν›„ 배포 +**λŒ€μƒ**: 178.104.200.7 (곡인 IP) / 192.168.123.100 (λ‚΄λΆ€ IP) + +--- + +## πŸ“‹ 사전 μ€€λΉ„ + +### 1. SSH ν‚€ μ„€μ • (졜초 1회) + +#### 1.1 λ‘œμ»¬μ—μ„œ SSH ν‚€ 생성 +```bash +ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" +``` + +#### 1.2 곡개 ν‚€λ₯Ό 원격 μ„œλ²„μ— 등둝 +```bash +ssh-copy-id -i ~/.ssh/id_ed25519.pub kjh2064@178.104.200.7 +# λ˜λŠ” λ‚΄λΆ€ IP +ssh-copy-id -i ~/.ssh/id_ed25519.pub kjh2064@192.168.123.100 +``` + +#### 1.3 SSH μ—°κ²° ν…ŒμŠ€νŠΈ +```bash +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 "echo 'βœ… μ—°κ²° 성곡'" +``` + +--- + +## πŸ” Step 1: ν™˜κ²½ νŒŒμ•… + +### μ‹œμŠ€ν…œ 정보 확인 + +```bash +# SSH 접속 +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 + +# 원격 μ„œλ²„μ—μ„œ μ‹€ν–‰: +# ───────────────────────────────────────────── + +# 1. μ‹œμŠ€ν…œ 정보 +uname -a +lsb_release -a + +# 2. λ””μŠ€ν¬ μƒνƒœ +df -h + +# 3. μ›Ή μ„œλ²„ μƒνƒœ +sudo systemctl status nginx + +# 4. μ›Ή μ„œλ²„ 경둜 +ls -la /var/www/quant/ +ls -la /var/www/quant/publish/ + +# 5. Nginx μ„€μ • 확인 +sudo cat /etc/nginx/sites-available/default | grep -A 10 "location" + +# 6. 포트 μƒνƒœ +sudo netstat -tuln | grep :80 + +# 7. μ‚¬μš©μž κΆŒν•œ 확인 +id +sudo -l +``` + +### μ˜ˆμƒ ν™˜κ²½ + +``` +βœ“ Linux (Ubuntu 20.04 λ˜λŠ” κ·Έ 이상) +βœ“ nginx (1.18 이상) +βœ“ /var/www/quant/ 디렉토리 쑴재 λ˜λŠ” 생성 κ°€λŠ₯ +βœ“ www-data λ˜λŠ” μœ μ‚¬ μ›Ή μ„œλ²„ μ‚¬μš©μž +βœ“ sudo κΆŒν•œ (webmaster κ·Έλ£Ή) +``` + +--- + +## πŸ“¦ Step 2: Release λΉŒλ“œ + +```bash +# λ‘œμ»¬μ—μ„œ μ‹€ν–‰ +cd /c/Temp/data_feed + +# Release λΉŒλ“œ +dotnet publish -c Release \ + -o src/dotnet/QuantEngine.Web/publish + +# κ²°κ³Ό 확인 +ls -lh src/dotnet/QuantEngine.Web/publish/ +``` + +--- + +## πŸš€ Step 3: 배포 슀크립트 μ‹€ν–‰ + +### 방법 1: μžλ™ 배포 슀크립트 (ꢌμž₯) + +```bash +# μŠ€ν¬λ¦½νŠΈμ— μ‹€ν–‰ κΆŒν•œ λΆ€μ—¬ +chmod +x deploy-manual.sh + +# 배포 μ‹€ν–‰ +./deploy-manual.sh 192.168.123.100 +# λ˜λŠ” +./deploy-manual.sh 178.104.200.7 +``` + +**μŠ€ν¬λ¦½νŠΈκ°€ μžλ™μœΌλ‘œ:** +- βœ“ SSH μ—°κ²° 확인 +- βœ“ 원격 ν™˜κ²½ νŒŒμ•… +- βœ“ λ°±μ—… 생성 +- βœ“ 파일 전솑 (rsync) +- βœ“ κΆŒν•œ μ„€μ • +- βœ“ nginx μž¬μ‹œμž‘ +- βœ“ ν—¬μŠ€ 체크 + +### 방법 2: μˆ˜λ™ 배포 (단계별) + +```bash +# 1. SSH 접속 +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 + +# 원격 μ„œλ²„μ—μ„œ: +# ───────────────────────────────────────────── + +# 2. λ°±μ—… 생성 +sudo mkdir -p /var/www/quant_backup +sudo cp -r /var/www/quant/publish \ + /var/www/quant_backup/quant_$(date +%Y%m%d_%H%M%S) +echo "βœ“ λ°±μ—… 생성 μ™„λ£Œ" + +# 3. 배포 디렉토리 μ€€λΉ„ +sudo mkdir -p /var/www/quant/publish +sudo chmod 777 /var/www/quant/publish + +# 4. κΆŒν•œ μ„€μ • +sudo chown -R www-data:www-data /var/www/quant/publish +sudo chmod -R 755 /var/www/quant/publish + +# 5. SSH μ’…λ£Œ +exit +``` + +```bash +# λ‘œμ»¬μ—μ„œ: 파일 전솑 +rsync -avz --delete \ + -e "ssh -i ~/.ssh/id_ed25519" \ + src/dotnet/QuantEngine.Web/publish/ \ + kjh2064@192.168.123.100:/var/www/quant/publish/ +``` + +```bash +# λ‹€μ‹œ SSH 접속 +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 + +# 원격 μ„œλ²„μ—μ„œ: +# ───────────────────────────────────────────── + +# 6. nginx μž¬μ‹œμž‘ +sudo systemctl restart nginx + +# 7. μƒνƒœ 확인 +sudo systemctl status nginx + +# μ’…λ£Œ +exit +``` + +--- + +## βœ… Step 4: 배포 검증 + +```bash +# 1. HTTP μƒνƒœ 확인 +curl -I http://178.104.200.7/quant/ +# λ˜λŠ” +curl -I http://192.168.123.100/quant/ + +# κΈ°λŒ€: HTTP/1.1 200 OK + +# 2. MudBlazor λ‘œλ“œ 확인 +curl -s http://178.104.200.7/quant/ | grep -c "MudBlazor" +# κΈ°λŒ€: > 0 + +# 3. νŽ˜μ΄μ§€ 제λͺ© 확인 +curl -s http://178.104.200.7/quant/ | grep -o ".*" +# κΈ°λŒ€: Quant Engine - Dashboard + +# 4. nginx 둜그 확인 +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 \ + 'sudo tail -20 /var/log/nginx/error.log' + +# 5. λΈŒλΌμš°μ € ν…ŒμŠ€νŠΈ +# http://178.104.200.7/quant/ 접속 +``` + +--- + +## πŸ”„ λ‘€λ°± (배포 μ‹€νŒ¨ μ‹œ) + +```bash +ssh -i ~/.ssh/id_ed25519 kjh2064@192.168.123.100 << 'EOF' +# μ΅œμ‹  λ°±μ—… 확인 +ls -lt /var/www/quant_backup/ + +# μ΅œμ‹  λ°±μ—…μœΌλ‘œ 볡원 +LATEST=$(ls -t /var/www/quant_backup | head -1) +echo "볡원 쀑: $LATEST" + +sudo cp -r /var/www/quant_backup/$LATEST/* /var/www/quant/publish/ + +# κΆŒν•œ μž¬μ„€μ • +sudo chown -R www-data:www-data /var/www/quant/publish +sudo chmod -R 755 /var/www/quant/publish + +# nginx μž¬μ‹œμž‘ +sudo systemctl restart nginx + +echo "βœ… λ‘€λ°± μ™„λ£Œ" +EOF +``` + +--- + +## πŸ“Š 배포 체크리슀트 + +### 배포 μ „ +``` +[ ] SSH ν‚€ μ„€μ • μ™„λ£Œ (~/.ssh/id_ed25519) +[ ] SSH μ—°κ²° ν…ŒμŠ€νŠΈ 성곡 +[ ] Release λΉŒλ“œ μ™„λ£Œ (24MB) +[ ] 배포 슀크립트 μ€€λΉ„ +``` + +### 배포 쀑 +``` +[ ] ν™˜κ²½ νŒŒμ•… μ™„λ£Œ +[ ] λ°±μ—… 생성 μ™„λ£Œ +[ ] 파일 전솑 μ™„λ£Œ +[ ] κΆŒν•œ μ„€μ • μ™„λ£Œ +[ ] nginx μž¬μ‹œμž‘ μ™„λ£Œ +``` + +### 배포 ν›„ +``` +[ ] HTTP 200 OK 확인 +[ ] MudBlazor λ¦¬μ†ŒμŠ€ λ‘œλ“œλ¨ +[ ] νŽ˜μ΄μ§€ 제λͺ© 확인 +[ ] nginx 둜그 μ—λŸ¬ μ—†μŒ +[ ] λΈŒλΌμš°μ € 접속 ν…ŒμŠ€νŠΈ +``` + +--- + +## πŸ†˜ 문제 ν•΄κ²° + +### SSH μ—°κ²° νƒ€μž„μ•„μ›ƒ +```bash +# 원인: IP μ£Όμ†Œ 였λ₯˜ λ˜λŠ” λ°©ν™”λ²½ + +# ν•΄κ²°: +1. IP 확인: 178.104.200.7 λ˜λŠ” 192.168.123.100? +2. SSH 포트 확인: 22 (κΈ°λ³Έκ°’) +3. λ°©ν™”λ²½ κ·œμΉ™ 확인 +4. 곡개 ν‚€ 등둝 μž¬ν™•μΈ +``` + +### κΆŒν•œ 였λ₯˜ (sudo λΆˆκ°€) +```bash +# 원인: sudo κΆŒν•œ μ—†μŒ + +# 확인: +sudo -l + +# ν•΄κ²°: κ΄€λ¦¬μžμ—κ²Œ webmaster κ·Έλ£Ή μΆ”κ°€ μš”μ²­ +``` + +### nginx μž¬μ‹œμž‘ μ‹€νŒ¨ +```bash +# 둜그 확인 +sudo systemctl status nginx +sudo journalctl -u nginx -n 20 + +# μ„€μ • ν…ŒμŠ€νŠΈ +sudo nginx -t + +# 포트 좩돌 확인 +sudo netstat -tuln | grep :80 +``` + +### 파일 κΆŒν•œ 문제 +```bash +# ν˜„μž¬ κΆŒν•œ 확인 +ls -la /var/www/quant/publish/ + +# κΆŒν•œ μˆ˜μ • +sudo chown -R www-data:www-data /var/www/quant/publish +sudo chmod -R 755 /var/www/quant/publish +``` + +--- + +## πŸ“š κ΄€λ ¨ 파일 + +``` +배포 슀크립트: +β”œβ”€β”€ deploy.sh (μžλ™ 배포, bash) +└── deploy-manual.sh (λŒ€ν™”ν˜• 배포, 이 파일) + +배포 κ°€μ΄λ“œ: +β”œβ”€β”€ DEPLOYMENT_GUIDE.md (전체 κ°€μ΄λ“œ) +β”œβ”€β”€ DEPLOYMENT_STEPS.md (단계별 μ§€μΉ¨) +β”œβ”€β”€ DEPLOYMENT_CHECKLIST.md (운영 체크리슀트) +└── DEPLOYMENT_SSH_GUIDE.md (이 파일) + +CI/CD: +β”œβ”€β”€ .gitea/workflows/deploy-prod.yml (μžλ™ν™”) +└── CI_CD_PIPELINE.md (CI/CD λ¬Έμ„œ) +``` + +--- + +## ⚑ λΉ λ₯Έ 배포 λͺ…λ Ήμ–΄ + +### ν•œ λ²ˆμ— 배포 +```bash +chmod +x deploy-manual.sh && ./deploy-manual.sh 192.168.123.100 +``` + +### λ‚΄λΆ€ IP μ‚¬μš© +```bash +# Giteaμ—μ„œ 배포할 λ•Œ (μžλ™ CI/CD) +DEPLOY_HOST=192.168.123.100 +``` + +### μ™ΈλΆ€ 접속 +```bash +# μ‚¬μš©μžκ°€ 접속할 λ•Œ +http://178.104.200.7/quant/ +``` + +--- + +**배포 μ€€λΉ„ μ™„λ£Œ!** πŸš€ + +deploy-manual.sh 슀크립트λ₯Ό μ‹€ν–‰ν•˜κ±°λ‚˜, μœ„μ˜ μˆ˜λ™ 단계λ₯Ό 따라 λ°°ν¬ν•˜μ„Έμš”. diff --git a/deploy-manual.sh b/deploy-manual.sh new file mode 100644 index 0000000..092be28 --- /dev/null +++ b/deploy-manual.sh @@ -0,0 +1,226 @@ +#!/bin/bash +# Quant Engine Manual Deployment Script +# 원격 μ„œλ²„μ— 직접 SSH μ ‘μ†ν•˜μ—¬ ν™˜κ²½ νŒŒμ•… ν›„ 배포 + +set -e + +# ═══════════════════════════════════════════════════════════════ +# μ„€μ • +# ═══════════════════════════════════════════════════════════════ + +DEPLOY_HOST="${1:-192.168.123.100}" +DEPLOY_USER="kjh2064" +SSH_KEY="${HOME}/.ssh/id_ed25519" +LOCAL_PUBLISH_DIR="$(pwd)/src/dotnet/QuantEngine.Web/publish" +REMOTE_DEPLOY_PATH="/var/www/quant" + +echo "πŸš€ Quant Engine Manual Deployment" +echo "═══════════════════════════════════════════════════════════════" +echo "Deploy Host: $DEPLOY_HOST" +echo "Deploy User: $DEPLOY_USER" +echo "Local Path: $LOCAL_PUBLISH_DIR" +echo "Remote Path: $REMOTE_DEPLOY_PATH" +echo "═══════════════════════════════════════════════════════════════" +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 1: SSH μ—°κ²° 확인 +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ“Š Step 1: SSH μ—°κ²° 및 ν™˜κ²½ νŒŒμ•…..." + +ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'ENVCHECK' +echo "βœ“ SSH μ—°κ²° 성곡" +echo "" +echo "μ‹œμŠ€ν…œ 정보:" +uname -a +echo "" + +echo "λ””μŠ€ν¬ μƒνƒœ:" +df -h | grep -E "^/dev|Filesystem|/$" +echo "" + +echo "μ„œλΉ„μŠ€ μƒνƒœ:" +sudo systemctl status nginx --no-pager 2>/dev/null | grep -E "Active:|Loaded:" || echo "⚠️ nginx μƒνƒœ 확인 ν•„μš”" +echo "" + +echo "μ›Ή μ„œλ²„ 디렉토리:" +if [ -d /var/www/quant/publish ]; then + echo "βœ“ /var/www/quant/publish 쑴재" + ls -lh /var/www/quant/publish | head -5 + echo "..." +else + echo "βœ— /var/www/quant/publish μ—†μŒ (첫 배포)" +fi +echo "" + +echo "μ›Ή μ„œλ²„ κΆŒν•œ:" +ls -ld /var/www/quant 2>/dev/null || echo "⚠️ /var/www/quant μ—†μŒ" +echo "" + +echo "Nginx 포트 확인:" +sudo netstat -tuln 2>/dev/null | grep :80 || echo "⚠️ 포트 80 확인 ν•„μš”" +ENVCHECK + +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 2: 배포 파일 μ€€λΉ„ 확인 +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ“¦ Step 2: 배포 파일 확인..." + +if [ ! -d "$LOCAL_PUBLISH_DIR" ]; then + echo "❌ 였λ₯˜: $LOCAL_PUBLISH_DIR μ—†μŒ" + echo "λ¨Όμ € 'dotnet publish -c Release'λ₯Ό μ‹€ν–‰ν•˜μ„Έμš”" + exit 1 +fi + +PACKAGE_SIZE=$(du -sh "$LOCAL_PUBLISH_DIR" | cut -f1) +FILE_COUNT=$(find "$LOCAL_PUBLISH_DIR" -type f | wc -l) + +echo "βœ“ 배포 νŒ¨ν‚€μ§€:" +echo " 크기: $PACKAGE_SIZE" +echo " 파일 수: $FILE_COUNT" +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 3: 사전 확인 +# ═══════════════════════════════════════════════════════════════ + +echo "βœ… 배포 μ „ 확인 사항:" +echo " [ ] Release λΉŒλ“œ μ™„λ£Œλ¨" +echo " [ ] publish 폴더 확인됨 ($PACKAGE_SIZE)" +echo " [ ] SSH ν‚€ 섀정됨 ($SSH_KEY)" +echo "" + +read -p "배포λ₯Ό μ§„ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ? (y/n) " -n 1 -r +echo "" + +if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "❌ 배포 μ·¨μ†Œλ¨" + exit 1 +fi + +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 4: λ°±μ—… 생성 +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ’Ύ Step 3: λ°±μ—… 생성..." + +ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'BACKUP' +set -e + +BACKUP_DIR="/var/www/quant_backup" +BACKUP_NAME="quant_backup_$(date +%Y%m%d_%H%M%S)" + +if [ -d /var/www/quant/publish ]; then + sudo mkdir -p "$BACKUP_DIR" + sudo cp -r /var/www/quant/publish "$BACKUP_DIR/$BACKUP_NAME" + echo "βœ“ λ°±μ—… 생성: $BACKUP_DIR/$BACKUP_NAME" + + # 졜근 5개만 μœ μ§€ + BACKUP_COUNT=$(ls -1 "$BACKUP_DIR" | wc -l) + if [ "$BACKUP_COUNT" -gt 5 ]; then + OLD_BACKUPS=$(ls -1t "$BACKUP_DIR" | tail -n +6) + for backup in $OLD_BACKUPS; do + sudo rm -rf "$BACKUP_DIR/$backup" + echo "🧹 였래된 λ°±μ—… μ‚­μ œ: $backup" + done + fi +else + echo "⚠️ κΈ°μ‘΄ 배포 μ—†μŒ (첫 배포)" +fi +BACKUP + +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 5: 파일 전솑 +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ“€ Step 4: 파일 전솑 (rsync)..." + +rsync -avz --delete \ + --rsh="ssh -i $SSH_KEY" \ + "$LOCAL_PUBLISH_DIR/" \ + "$DEPLOY_USER@$DEPLOY_HOST:$REMOTE_DEPLOY_PATH/publish/" + +echo "βœ“ 파일 전솑 μ™„λ£Œ" +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 6: κΆŒν•œ μ„€μ • 및 μ„œλΉ„μŠ€ μž¬μ‹œμž‘ +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ”§ Step 5: κΆŒν•œ μ„€μ • 및 μ„œλΉ„μŠ€ μž¬μ‹œμž‘..." + +ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" << 'FINALIZE' +set -e + +DEPLOY_PATH="/var/www/quant" + +echo " κΆŒν•œ μ„€μ • 쀑..." +sudo chown -R www-data:www-data "$DEPLOY_PATH/publish" 2>/dev/null || true +sudo chmod -R 755 "$DEPLOY_PATH/publish" 2>/dev/null || true +echo " βœ“ κΆŒν•œ μ„€μ • μ™„λ£Œ" + +echo " nginx μž¬μ‹œμž‘ 쀑..." +sudo systemctl restart nginx 2>/dev/null || echo " ⚠️ nginx μž¬μ‹œμž‘ μ‹€νŒ¨ (sudo κΆŒν•œ 확인)" +sleep 2 + +if sudo systemctl is-active --quiet nginx 2>/dev/null; then + echo " βœ“ nginx μž¬μ‹œμž‘ μ™„λ£Œ" +else + echo " ⚠️ nginx μƒνƒœ 확인 ν•„μš”" +fi +FINALIZE + +echo "" + +# ═══════════════════════════════════════════════════════════════ +# Step 7: ν—¬μŠ€ 체크 +# ═══════════════════════════════════════════════════════════════ + +echo "πŸ§ͺ Step 6: ν—¬μŠ€ 체크..." + +for i in {1..5}; do + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ + http://$DEPLOY_HOST/quant/ 2>/dev/null || echo "000") + + if [ "$HTTP_CODE" = "200" ]; then + echo "βœ“ Health check PASS (HTTP 200)" + break + fi + + echo " μ‹œλ„ $i/5: HTTP $HTTP_CODE (λŒ€κΈ° 쀑...)" + sleep 2 +done + +echo "" + +# ═══════════════════════════════════════════════════════════════ +# 배포 μ™„λ£Œ +# ═══════════════════════════════════════════════════════════════ + +echo "═══════════════════════════════════════════════════════════════" +echo "βœ… 배포 μ™„λ£Œ!" +echo "═══════════════════════════════════════════════════════════════" +echo "" +echo "πŸ“Š 배포 정보:" +echo " URL: http://$DEPLOY_HOST/quant/" +echo " 경둜: $REMOTE_DEPLOY_PATH/publish" +echo " 크기: $PACKAGE_SIZE" +echo "" +echo "πŸ” 둜그 확인:" +echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST 'sudo tail -50 /var/log/nginx/error.log'" +echo "" +echo "πŸ”„ λ‘€λ°± (ν•„μš”μ‹œ):" +echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST << 'EOF'" +echo " LATEST=\$(ls -t /var/www/quant_backup | head -1)" +echo " sudo cp -r /var/www/quant_backup/\$LATEST/* /var/www/quant/publish/" +echo " sudo systemctl restart nginx" +echo " EOF" +echo ""