chore(ci): Update Gitea Actions CI/CD pipeline for v9 production deployment
- Configure internal IP deployment: 172.17.0.1 (hz-prod-01) - Set deployment path to /home/kjh2064/quantengine_active - Use quantengine systemd service for app management - Implement service lifecycle (stop → backup → extract → start) - Add health checks against localhost:5000 (quantengine) - Update Nginx reverse proxy verification (already configured) - Add comprehensive deployment report and Slack notifications - Include post-deployment performance metrics collection CI/CD Flow: 1. Build & Test: Release build, validation, .tar.gz creation 2. Deploy: Service stop, backup, file transfer, service start 3. Health Check: localhost:5000 verification via Nginx proxy 4. Post-Deploy: Performance metrics and deployment checklist Environment: hz-prod-01 (Public: 178.104.200.7 / Internal: 172.17.0.1) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,14 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DEPLOY_HOST: 192.168.123.100
|
||||
# NOTE: Gitea와 운영서버가 원격지의 같은 서버에 있으므로 내부 IP 사용
|
||||
# Gitea (CI/CD) → SSH (내부 192.168.123.100) → 운영서버
|
||||
# 외부 사용자: 178.104.200.7 → nginx 포트포워딩 → 192.168.123.100/quant
|
||||
DEPLOY_HOST: 172.17.0.1
|
||||
# NOTE: Gitea와 운영서버가 같은 호스트에 있음 (hz-prod-01)
|
||||
# 구조: 공인 IP 178.104.200.7/quant → Nginx reverse proxy → localhost:5000 (quantengine)
|
||||
# 배포: .NET DLL을 /home/kjh2064/quantengine_active에 배포
|
||||
# Nginx 설정: /etc/nginx/sites-available/gitea-ip.conf (이미 구성됨)
|
||||
DEPLOY_USER: kjh2064
|
||||
DEPLOY_PATH: /var/www/quant
|
||||
DEPLOY_PATH: /home/kjh2064/quantengine_active
|
||||
SERVICE_NAME: quantengine
|
||||
DOTNET_VERSION: '10.0.x'
|
||||
|
||||
jobs:
|
||||
@@ -105,24 +107,36 @@ jobs:
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keyscan -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true
|
||||
|
||||
- name: Create Backup
|
||||
- name: Stop Service and Create Backup
|
||||
run: |
|
||||
echo "📦 Creating backup on production server..."
|
||||
echo "📦 Stopping service and creating backup..."
|
||||
ssh -i ~/.ssh/id_ed25519 ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} << 'EOF'
|
||||
set -e
|
||||
BACKUP_DIR="/var/www/quant_backup"
|
||||
BACKUP_NAME="quant_backup_$(date +%Y%m%d_%H%M%S)"
|
||||
BACKUP_DIR="/home/kjh2064/quantengine_backup"
|
||||
BACKUP_NAME="quantengine_$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
sudo mkdir -p $BACKUP_DIR
|
||||
if [ -d ${{ env.DEPLOY_PATH }}/publish ]; then
|
||||
sudo cp -r ${{ env.DEPLOY_PATH }}/publish "$BACKUP_DIR/$BACKUP_NAME"
|
||||
# Stop service
|
||||
echo "⏹️ Stopping quantengine service..."
|
||||
sudo systemctl stop ${{ env.SERVICE_NAME }}
|
||||
sleep 2
|
||||
|
||||
# Create backup
|
||||
mkdir -p $BACKUP_DIR
|
||||
if [ -d ${{ env.DEPLOY_PATH }} ]; then
|
||||
cp -r ${{ env.DEPLOY_PATH }} "$BACKUP_DIR/$BACKUP_NAME"
|
||||
echo "✅ Backup created: $BACKUP_DIR/$BACKUP_NAME"
|
||||
|
||||
# Keep only last 5 backups
|
||||
ls -t $BACKUP_DIR | tail -n +6 | xargs -I {} sudo rm -rf "$BACKUP_DIR/{}"
|
||||
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
|
||||
rm -rf "$BACKUP_DIR/$backup"
|
||||
done
|
||||
echo "🧹 Old backups cleaned"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ No existing deployment found, skipping backup"
|
||||
echo "⚠️ No existing deployment found"
|
||||
fi
|
||||
EOF
|
||||
|
||||
@@ -152,38 +166,41 @@ jobs:
|
||||
ARCHIVE_NAME=$(ls -1 /tmp/quant-deploy/quant-engine-release-*.tar.gz | head -1)
|
||||
|
||||
# Create deployment directory
|
||||
sudo mkdir -p "$DEPLOY_PATH/publish"
|
||||
sudo chmod 777 "$DEPLOY_PATH/publish"
|
||||
mkdir -p "$DEPLOY_PATH"
|
||||
|
||||
# Extract new package
|
||||
tar -xzf "$ARCHIVE_NAME" -C "$DEPLOY_PATH/publish"
|
||||
echo "✅ Package extracted"
|
||||
tar -xzf "$ARCHIVE_NAME" -C "$DEPLOY_PATH"
|
||||
echo "✅ Package extracted to $DEPLOY_PATH"
|
||||
|
||||
# Set permissions
|
||||
sudo chown -R www-data:www-data "$DEPLOY_PATH/publish"
|
||||
sudo chmod -R 755 "$DEPLOY_PATH/publish"
|
||||
echo "✅ Permissions set"
|
||||
# Verify key files
|
||||
if [ -f "$DEPLOY_PATH/QuantEngine.Web.dll" ]; then
|
||||
echo "✅ QuantEngine.Web.dll verified"
|
||||
else
|
||||
echo "❌ QuantEngine.Web.dll not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup temp
|
||||
rm -rf /tmp/quant-deploy
|
||||
EOF
|
||||
|
||||
- name: Restart Services
|
||||
- name: Start Service
|
||||
run: |
|
||||
echo "🔄 Restarting services..."
|
||||
echo "🔄 Starting quantengine service..."
|
||||
ssh -i ~/.ssh/id_ed25519 ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} << 'EOF'
|
||||
set -e
|
||||
|
||||
# Restart nginx
|
||||
sudo systemctl restart nginx
|
||||
sleep 2
|
||||
# Start service
|
||||
sudo systemctl start ${{ env.SERVICE_NAME }}
|
||||
sleep 3
|
||||
|
||||
# Check status
|
||||
if sudo systemctl is-active --quiet nginx; then
|
||||
echo "✅ nginx restarted successfully"
|
||||
if sudo systemctl is-active --quiet ${{ env.SERVICE_NAME }}; then
|
||||
echo "✅ ${{ env.SERVICE_NAME }} started successfully"
|
||||
sudo systemctl status ${{ env.SERVICE_NAME }} | head -5
|
||||
else
|
||||
echo "❌ nginx failed to start"
|
||||
sudo systemctl status nginx
|
||||
echo "❌ ${{ env.SERVICE_NAME }} failed to start"
|
||||
sudo systemctl status ${{ env.SERVICE_NAME }}
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
@@ -192,13 +209,13 @@ jobs:
|
||||
run: |
|
||||
echo "🧪 Running health checks..."
|
||||
|
||||
# Wait for service to be ready
|
||||
# Wait for service to be ready (localhost:5000 through Nginx)
|
||||
for i in {1..30}; do
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
http://${{ env.DEPLOY_HOST }}/quant/ || echo "000")
|
||||
"http://127.0.0.1:5000/" || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ Health check passed (HTTP $HTTP_CODE)"
|
||||
echo "✅ Health check passed (HTTP $HTTP_CODE at localhost:5000)"
|
||||
break
|
||||
fi
|
||||
|
||||
@@ -208,6 +225,9 @@ jobs:
|
||||
|
||||
if [ "$HTTP_CODE" != "200" ]; then
|
||||
echo "❌ Health check failed after 60 seconds"
|
||||
echo "Service logs:"
|
||||
ssh -i ~/.ssh/id_ed25519 ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }} \
|
||||
"sudo journalctl -u ${{ env.SERVICE_NAME }} -n 20" || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -215,8 +235,9 @@ jobs:
|
||||
run: |
|
||||
echo "📊 Verifying deployment..."
|
||||
|
||||
# Check MudBlazor is loaded
|
||||
MUDBLAZOR_CHECK=$(curl -s http://${{ env.DEPLOY_HOST }}/quant/ | grep -c "MudBlazor" || echo "0")
|
||||
# Check MudBlazor is loaded (via public IP)
|
||||
PUBLIC_IP="178.104.200.7"
|
||||
MUDBLAZOR_CHECK=$(curl -s "http://$PUBLIC_IP/quant/" | grep -c "MudBlazor" || echo "0")
|
||||
|
||||
if [ "$MUDBLAZOR_CHECK" -gt "0" ]; then
|
||||
echo "✅ MudBlazor UI loaded successfully"
|
||||
@@ -225,7 +246,7 @@ jobs:
|
||||
fi
|
||||
|
||||
# Get page title
|
||||
PAGE_TITLE=$(curl -s http://${{ env.DEPLOY_HOST }}/quant/ | grep -o "<title>.*</title>" | head -1)
|
||||
PAGE_TITLE=$(curl -s "http://$PUBLIC_IP/quant/" | grep -o "<title>.*</title>" | head -1)
|
||||
echo "📄 Page title: $PAGE_TITLE"
|
||||
|
||||
- name: Generate Deployment Report
|
||||
@@ -233,7 +254,7 @@ jobs:
|
||||
run: |
|
||||
cat > deployment-report.txt << EOF
|
||||
═══════════════════════════════════════════════════════
|
||||
Quant Engine Deployment Report
|
||||
Quant Engine v9 Deployment Report
|
||||
═══════════════════════════════════════════════════════
|
||||
|
||||
Deployment Date: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
|
||||
@@ -241,27 +262,42 @@ jobs:
|
||||
Commit: ${{ github.sha }}
|
||||
Branch: ${{ github.ref }}
|
||||
|
||||
Target Server: ${{ env.DEPLOY_HOST }}
|
||||
🎯 Target Environment
|
||||
Server: hz-prod-01
|
||||
Internal IP: ${{ env.DEPLOY_HOST }}
|
||||
Public IP: 178.104.200.7
|
||||
Deploy Path: ${{ env.DEPLOY_PATH }}
|
||||
Service: ${{ env.SERVICE_NAME }}
|
||||
|
||||
Status: COMPLETED
|
||||
📊 Deployment Status: COMPLETED
|
||||
|
||||
✅ Release Build: Successful
|
||||
✅ Package Created: 24MB
|
||||
✅ Backup Created: /var/www/quant_backup/
|
||||
✅ Package Deployed: ${{ env.DEPLOY_PATH }}/publish
|
||||
✅ Services Restarted: nginx
|
||||
✅ Health Check: PASS
|
||||
✅ MudBlazor UI: Verified
|
||||
✅ Package Created: 24MB+
|
||||
✅ Backup Created: /home/kjh2064/quantengine_backup/
|
||||
✅ Package Deployed: ${{ env.DEPLOY_PATH }}
|
||||
✅ Service Started: ${{ env.SERVICE_NAME }}
|
||||
✅ Health Check: PASS (localhost:5000)
|
||||
✅ MudBlazor UI: Verified via public IP
|
||||
|
||||
Access: http://${{ env.DEPLOY_HOST }}/quant/
|
||||
🌐 Access Information
|
||||
Public URL: http://178.104.200.7/quant/
|
||||
Service Port: 127.0.0.1:5000
|
||||
Nginx Config: /etc/nginx/sites-available/gitea-ip.conf
|
||||
|
||||
Logs:
|
||||
- Deployment: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
- nginx: ssh kjh2064@${{ env.DEPLOY_HOST }} 'sudo tail -50 /var/log/nginx/error.log'
|
||||
📝 Service Architecture
|
||||
- Nginx (reverse proxy) listens on port 80/443
|
||||
- /quant/ path → localhost:5000 (quantengine service)
|
||||
- quantengine runs as user kjh2064
|
||||
- WorkingDirectory: /home/kjh2064/quantengine_active
|
||||
|
||||
Rollback Command (if needed):
|
||||
ssh kjh2064@${{ env.DEPLOY_HOST }} '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'
|
||||
🔍 Monitoring & Logs
|
||||
- Service: sudo systemctl status ${{ env.SERVICE_NAME }}
|
||||
- Logs: sudo journalctl -u ${{ env.SERVICE_NAME }} -f
|
||||
- Nginx: sudo tail -f /var/log/nginx/error.log
|
||||
- Deployment Log: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
🔄 Rollback Command (if needed):
|
||||
ssh kjh2064@${{ env.DEPLOY_HOST }} 'LATEST=\$(ls -t /home/kjh2064/quantengine_backup | head -1); cp -r /home/kjh2064/quantengine_backup/\$LATEST/* /home/kjh2064/quantengine_active/ && sudo systemctl restart ${{ env.SERVICE_NAME }}'
|
||||
|
||||
═══════════════════════════════════════════════════════
|
||||
EOF
|
||||
@@ -293,12 +329,12 @@ jobs:
|
||||
-d "{
|
||||
\"attachments\": [{
|
||||
\"color\": \"$COLOR\",
|
||||
\"title\": \"$EMOJI Quant Engine Deployment\",
|
||||
\"title\": \"$EMOJI Quant Engine v9 Deployment\",
|
||||
\"text\": \"Run #${{ github.run_number }}\",
|
||||
\"fields\": [
|
||||
{\"title\": \"Status\", \"value\": \"$STATUS\", \"short\": true},
|
||||
{\"title\": \"Server\", \"value\": \"${{ env.DEPLOY_HOST }}\", \"short\": true},
|
||||
{\"title\": \"URL\", \"value\": \"http://${{ env.DEPLOY_HOST }}/quant/\", \"short\": false}
|
||||
{\"title\": \"Service\", \"value\": \"${{ env.SERVICE_NAME }}\", \"short\": true},
|
||||
{\"title\": \"URL\", \"value\": \"http://178.104.200.7/quant/\", \"short\": false}
|
||||
],
|
||||
\"ts\": $(date +%s)
|
||||
}]
|
||||
|
||||
Reference in New Issue
Block a user