name: Deploy to Production on: push: branches: [ main ] jobs: deploy: name: Deploy to Server runs-on: ubuntu-latest steps: - name: Deploy via SSH uses: appleboy/ssh-action@v1.1.0 with: host: ${{ secrets.SERVER_HOST }} username: ${{ secrets.SERVER_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: | set -e echo "๐Ÿš€ Starting deployment..." # Navigate to project directory cd /root/docfast # Check current git status echo "๐Ÿ“‹ Current status:" git status --short || true # Pull latest changes echo "๐Ÿ“ฅ Pulling latest changes..." git fetch origin git pull origin main # Tag current running image for rollback echo "๐Ÿท๏ธ Tagging current image for rollback..." TIMESTAMP=$(date +%Y%m%d-%H%M%S) docker tag docfast-docfast:latest docfast-docfast:rollback-$TIMESTAMP || echo "No existing image to tag" # Build new image echo "๐Ÿ”จ Building new Docker image..." docker compose build --no-cache # Stop services gracefully echo "โน๏ธ Stopping services..." docker compose down --timeout 30 # Start services echo "โ–ถ๏ธ Starting services..." docker compose up -d # Wait for service to be ready echo "โฑ๏ธ Waiting for service to be ready..." for i in {1..30}; do if curl -f -s http://127.0.0.1:3100/health > /dev/null; then echo "โœ… Service is healthy!" break fi if [ $i -eq 30 ]; then echo "โŒ Service failed to start - initiating rollback..." docker compose down # Try to rollback to previous image ROLLBACK_IMAGE=$(docker images --format "table {{.Repository}}:{{.Tag}}" | grep "docfast-docfast:rollback-" | head -n1 | tr -s ' ' | cut -d' ' -f1) if [ ! -z "$ROLLBACK_IMAGE" ]; then echo "๐Ÿ”„ Rolling back to $ROLLBACK_IMAGE" docker tag $ROLLBACK_IMAGE docfast-docfast:latest docker compose up -d # Wait for rollback to be healthy sleep 10 if curl -f -s http://127.0.0.1:3100/health > /dev/null; then echo "โœ… Rollback successful" else echo "โŒ Rollback failed - manual intervention required" fi else echo "โŒ No rollback image available" fi exit 1 fi echo "โณ Attempt $i/30 - waiting 5 seconds..." sleep 5 done # Cleanup old rollback images (keep last 5) echo "๐Ÿงน Cleaning up old rollback images..." docker images --format "table {{.Repository}}:{{.Tag}}" | grep "docfast-docfast:rollback-" | tail -n +6 | awk '{print $1":"$2}' | xargs -r docker rmi || true # Final health check and status echo "๐Ÿ” Final health check..." HEALTH_STATUS=$(curl -f -s http://127.0.0.1:3100/health || echo "UNHEALTHY") echo "Health status: $HEALTH_STATUS" echo "๐Ÿ“Š Service status:" docker compose ps echo "๐ŸŽ‰ Deployment completed successfully!"