bash
DevOps
PM2 Deployment Script
Zero-downtime deployment script for Node.js apps using PM2 with health checks, rollback support, and deployment logging.
Apex Logic
0 copies
bash
#!/bin/bash
# PM2 Zero-Downtime Deployment Script
set -euo pipefail
APP_NAME="${1:-myapp}"
APP_DIR="${2:-/var/www/$APP_NAME}"
BRANCH="${3:-main}"
LOG_FILE="/var/log/deploy-${APP_NAME}.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"; }
log "=== Starting deployment of $APP_NAME ==="
cd "$APP_DIR"
# Save current commit for rollback
PREV_COMMIT=$(git rev-parse HEAD)
log "Current commit: $PREV_COMMIT"
# Pull latest changes
log "Pulling from $BRANCH..."
git fetch origin "$BRANCH"
git reset --hard "origin/$BRANCH"
NEW_COMMIT=$(git rev-parse HEAD)
log "New commit: $NEW_COMMIT"
if [ "$PREV_COMMIT" = "$NEW_COMMIT" ]; then
log "No changes detected. Skipping deployment."
exit 0
fi
# Install dependencies
log "Installing dependencies..."
npm ci --production
# Run migrations if script exists
if [ -f "scripts/migrate.js" ]; then
log "Running migrations..."
node scripts/migrate.js
fi
# Reload with zero downtime
log "Reloading PM2 processes..."
pm2 reload "$APP_NAME" --update-env
# Health check
sleep 5
if pm2 show "$APP_NAME" | grep -q "online"; then
log "Deployment successful! App is online."
else
log "ERROR: App not healthy after deploy. Rolling back..."
git reset --hard "$PREV_COMMIT"
npm ci --production
pm2 reload "$APP_NAME" --update-env
log "Rolled back to $PREV_COMMIT"
exit 1
fi
log "=== Deployment complete ==="