PM2 is the most popular process manager for Node.js applications. It keeps your apps running, handles restarts, and provides powerful monitoring. This guide covers everything from basics to advanced usage.
What is PM2?
PM2 (Process Manager 2) is a production process manager for Node.js with:
- Process management (start, stop, restart)
- Auto-restart on crashes
- Load balancing with cluster mode
- Log management
- Monitoring dashboard
- Deployment system
Installation
Global Installation
npm install -g pm2
Verify Installation
pm2 --version
Basic Usage
Start an Application
# Start a script
pm2 start app.js
# Start with a name
pm2 start app.js --name my-app
# Start npm script
pm2 start npm --name my-app -- start
Manage Processes
pm2 list # List all processes
pm2 stop my-app # Stop a process
pm2 restart my-app # Restart a process
pm2 delete my-app # Remove from PM2
pm2 stop all # Stop all processes
pm2 restart all # Restart all processes
View Logs
pm2 logs # All logs
pm2 logs my-app # Specific app logs
pm2 logs --lines 100 # Last 100 lines
pm2 flush # Clear all logs
Ecosystem Configuration
For complex setups, use an ecosystem file.
Create ecosystem.config.js
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
instances: 2,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}]
};
Start with Ecosystem
pm2 start ecosystem.config.js
pm2 start ecosystem.config.js --env production
Cluster Mode
Cluster mode runs multiple instances for better performance.
Enable Clustering
# Start with specific instances
pm2 start app.js -i 4
# Use all CPU cores
pm2 start app.js -i max
Ecosystem Cluster Config
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
instance_var: 'INSTANCE_ID'
}]
};
Scale Instances
pm2 scale my-app 4 # Scale to 4 instances
pm2 scale my-app +2 # Add 2 instances
pm2 scale my-app -1 # Remove 1 instance
Auto-Restart Configuration
On System Reboot
pm2 startup # Generate startup script
pm2 save # Save current process list
On File Changes (Development)
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
watch: true,
ignore_watch: ['node_modules', 'logs'],
watch_options: {
followSymlinks: false
}
}]
};
On Memory Limit
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
max_memory_restart: '500M'
}]
};
Monitoring
Built-in Monitor
pm2 monit
Shows real-time:
- CPU usage
- Memory usage
- Loop delay
- Request count
Process Information
pm2 show my-app # Detailed info
pm2 describe my-app # Same as show
PM2 Plus (Web Dashboard)
pm2 plus # Connect to PM2 Plus
Provides:
- Web-based dashboard
- Historical metrics
- Alerting
- Remote management
Log Management
Log Configuration
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
output: './logs/out.log',
error: './logs/error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss',
merge_logs: true
}]
};
Log Rotation
Install pm2-logrotate:
pm2 install pm2-logrotate
Configure:
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
Environment Variables
In Ecosystem File
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 8080
},
env_staging: {
NODE_ENV: 'staging',
PORT: 3001
}
}]
};
Switch Environments
pm2 start ecosystem.config.js --env production
pm2 restart my-app --env staging
Deployment
Deployment Configuration
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js'
}],
deploy: {
production: {
user: 'deploy',
host: 'your_server_ip',
ref: 'origin/main',
repo: 'git@github.com:user/repo.git',
path: '/var/www/my-app',
'pre-deploy-local': '',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};
Deploy Commands
# Initial setup
pm2 deploy production setup
# Deploy
pm2 deploy production
# Rollback
pm2 deploy production revert 1
Graceful Shutdown
Handle shutdown signals properly:
In Your App
process.on('SIGINT', async () => {
console.log('Shutting down gracefully...');
// Close database connections
await db.close();
// Close server
server.close(() => {
console.log('Server closed');
process.exit(0);
});
// Force exit after timeout
setTimeout(() => {
process.exit(1);
}, 10000);
});
PM2 Configuration
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
kill_timeout: 5000,
wait_ready: true,
listen_timeout: 10000
}]
};
Common Patterns
Discord Bot
module.exports = {
apps: [{
name: 'discord-bot',
script: 'bot.js',
instances: 1,
autorestart: true,
max_memory_restart: '500M',
env: {
NODE_ENV: 'production',
DISCORD_TOKEN: 'your_token'
}
}]
};
API Server with Clustering
module.exports = {
apps: [{
name: 'api-server',
script: 'server.js',
instances: 'max',
exec_mode: 'cluster',
max_memory_restart: '1G',
env_production: {
NODE_ENV: 'production',
PORT: 3000
}
}]
};
Multiple Apps
module.exports = {
apps: [
{
name: 'api',
script: 'api/server.js',
instances: 4,
exec_mode: 'cluster'
},
{
name: 'worker',
script: 'worker/index.js',
instances: 2
},
{
name: 'scheduler',
script: 'scheduler/cron.js',
instances: 1
}
]
};
Troubleshooting
Process Keeps Restarting
Check logs for errors:
pm2 logs my-app --err --lines 50
High Memory Usage
- Check for memory leaks
- Set max_memory_restart
- Review your code for issues
Cluster Mode Issues
Not all apps work in cluster mode. Ensure:
- No shared state between instances
- Use Redis for sessions
- Stateless design
Useful Commands Reference
# Process management
pm2 start app.js
pm2 stop all
pm2 restart all
pm2 delete all
# Monitoring
pm2 list
pm2 monit
pm2 show app-name
# Logs
pm2 logs
pm2 flush
# System
pm2 startup
pm2 save
pm2 unstartup
# Updates
pm2 update
Conclusion
PM2 is essential for running Node.js in production. It handles crashes, provides monitoring, and enables zero-downtime deployments. Start with basic usage and gradually adopt advanced features as needed.
HeavenCloud hosting works perfectly with PM2, providing the reliable infrastructure your Node.js applications need.