patternjavascriptMajor
Zero-downtime deployments with rolling restarts and health checks
Viewed 0 times
zero downtimerolling restartdeploymentpm2graceful shutdownhealth checkrollback
Problem
Deploying new code requires restarting the server, causing a window where requests fail or get dropped.
Solution
Implement a deploy script that validates before switching:
#!/bin/bash
set -e # Exit on any error
APP_DIR=/opt/myapp
NEW_DIR=/opt/myapp-new
# 1. Pull and build new version in separate directory
git clone $REPO $NEW_DIR
cd $NEW_DIR && npm ci && npm run build
# 2. Validate the build starts correctly
NODE_ENV=production timeout 10 node $NEW_DIR/dist/server.js --check 2>&1 | grep 'OK'
# 3. Copy new files and reload (pm2 cluster reload is atomic)
cp -r $NEW_DIR/dist $APP_DIR/
pm2 reload myapp
# 4. Wait and verify health
sleep 5
curl -f http://localhost:3000/health || (pm2 reload myapp --revert && exit 1)
# 5. Cleanup
rm -rf $NEW_DIR
echo 'Deploy complete'Why
pm2 reload in cluster mode sends SIGINT to one worker, waits for it to finish serving requests, starts a new worker, then proceeds to the next — achieving zero-downtime rolling restart.
Gotchas
- SIGINT must be handled gracefully in the app — close database connections and finish in-flight requests
- If using sticky sessions, a rolling restart can break existing sessions on that worker
- Database migrations must be backward compatible — run them before deploying new code
- Have a rollback plan tested before production deploy — not just after something goes wrong
Revisions (0)
No revisions yet.