# πŸ” SSH 배포 κ°€μ΄λ“œ (v9) **λͺ©ν‘œ**: SSH둜 원격 μ„œλ²„μ— 직접 μ ‘μ†ν•˜μ—¬ 배포 **ν™˜κ²½**: hz-prod-01 (곡인 IP 178.104.200.7 / λ‚΄λΆ€ IP 172.17.0.1) --- ## πŸ“‹ 사전 μ€€λΉ„ ### 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 ``` #### 1.3 SSH μ—°κ²° ν…ŒμŠ€νŠΈ ```bash ssh -i ~/.ssh/id_ed25519 kjh2064@178.104.200.7 "echo 'βœ… μ—°κ²° 성곡'" ``` --- ## πŸ” Step 1: ν™˜κ²½ νŒŒμ•… ### 원격 μ„œλ²„ 정보 확인 ```bash 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 λΉŒλ“œ ```bash # 둜컬 개발 λ¨Έμ‹ μ—μ„œ μ‹€ν–‰ 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: μžλ™ 배포 슀크립트 (ꢌμž₯) ```bash # μŠ€ν¬λ¦½νŠΈμ— μ‹€ν–‰ κΆŒν•œ λΆ€μ—¬ chmod +x deploy-production.sh # 배포 μ‹€ν–‰ ./deploy-production.sh # λ˜λŠ” ./deploy-manual.sh 178.104.200.7 ``` **μŠ€ν¬λ¦½νŠΈκ°€ μžλ™μœΌλ‘œ:** - βœ“ SSH μ—°κ²° 확인 - βœ“ 원격 ν™˜κ²½ νŒŒμ•… - βœ“ μ„œλΉ„μŠ€ 쀑지 - βœ“ λ°±μ—… 생성 - βœ“ 파일 전솑 (rsync) - βœ“ 파일 검증 - βœ“ μ„œλΉ„μŠ€ μ‹œμž‘ - βœ“ ν—¬μŠ€ 체크 ### 방법 2: μˆ˜λ™ 배포 (단계별) #### Step 2-1: SSH 접속 ```bash ssh -i ~/.ssh/id_ed25519 kjh2064@178.104.200.7 ``` #### Step 2-2: μ„œλΉ„μŠ€ 쀑지 및 λ°±μ—… ```bash # 원격 μ„œλ²„μ—μ„œ μ‹€ν–‰: 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 μ’…λ£Œ ```bash exit ``` #### Step 2-4: 파일 전솑 (λ‘œμ»¬μ—μ„œ) ```bash 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: μ„œλΉ„μŠ€ μ‹œμž‘ ```bash 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 μƒνƒœ 확인 ```bash # 곡인 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 λ¦¬μ†ŒμŠ€ 확인 ```bash curl -s http://178.104.200.7/quant/ | grep -c "MudBlazor" # κΈ°λŒ€: > 0 ``` ### νŽ˜μ΄μ§€ 제λͺ© 확인 ```bash curl -s http://178.104.200.7/quant/ | grep -o ".*" # κΈ°λŒ€: Quant Engine - Dashboard ``` ### 둜그 확인 ```bash # μ„œλΉ„μŠ€ 둜그 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/ ``` --- ## πŸ”„ λ‘€λ°± (배포 μ‹€νŒ¨ μ‹œ) ### μžλ™ λ‘€λ°± 슀크립트 ```bash 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 μ—°κ²° νƒ€μž„μ•„μ›ƒ ```bash # 확인: 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 ``` ### μ„œλΉ„μŠ€ μ‹œμž‘ μ‹€νŒ¨ ```bash # 둜그 확인 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 ν”„λ‘μ‹œ 였λ₯˜ ```bash # 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' ``` ### 파일 κΆŒν•œ 문제 ```bash # ν˜„μž¬ κΆŒν•œ 확인 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 ``` --- ## ⚑ λΉ λ₯Έ 배포 λͺ…λ Ήμ–΄ ### ν•œ λ²ˆμ— 배포 ```bash chmod +x deploy-production.sh && ./deploy-production.sh ``` ### λ‚΄λΆ€ IP μ‚¬μš© (선택) ```bash ./deploy-manual.sh 172.17.0.1 ``` ### 곡인 IP μ‚¬μš© (ꢌμž₯) ```bash ./deploy-manual.sh 178.104.200.7 ``` ### μƒνƒœ 확인 ```bash ssh kjh2064@178.104.200.7 'sudo systemctl status quantengine' ``` ### 둜그 λͺ¨λ‹ˆν„°λ§ ```bash ssh kjh2064@178.104.200.7 'sudo journalctl -u quantengine -f' ``` --- **배포 μ€€λΉ„ μ™„λ£Œ!** πŸš€ `deploy-production.sh` λ˜λŠ” `deploy-manual.sh` 슀크립트λ₯Ό μ‹€ν–‰ν•˜κ±°λ‚˜, μœ„μ˜ μˆ˜λ™ 단계λ₯Ό 따라 λ°°ν¬ν•˜μ„Έμš”.