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.
PM2 (Process Manager 2) is a production process manager for Node.js with:
npm install -g pm2
pm2 --version
# 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
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
pm2 logs # All logs
pm2 logs my-app # Specific app logs
pm2 logs --lines 100 # Last 100 lines
pm2 flush # Clear all logs
For complex setups, use an ecosystem file.
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'
}
}]
};
pm2 start ecosystem.config.js
pm2 start ecosystem.config.js --env production
Cluster mode runs multiple instances for better performance.
# Start with specific instances
pm2 start app.js -i 4
# Use all CPU cores
pm2 start app.js -i max
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
instance_var: 'INSTANCE_ID'
}]
};
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
pm2 startup # Generate startup script
pm2 save # Save current process list
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
watch: true,
ignore_watch: ['node_modules', 'logs'],
watch_options: {
followSymlinks: false
}
}]
};
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
max_memory_restart: '500M'
}]
};
pm2 monit
Shows real-time:
pm2 show my-app # Detailed info
pm2 describe my-app # Same as show
pm2 plus # Connect to PM2 Plus
Provides:
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
}]
};
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
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
}
}]
};
pm2 start ecosystem.config.js --env production
pm2 restart my-app --env staging
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': ''
}
}
};
# Initial setup
pm2 deploy production setup
# Deploy
pm2 deploy production
# Rollback
pm2 deploy production revert 1
Handle shutdown signals properly:
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);
});
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
kill_timeout: 5000,
wait_ready: true,
listen_timeout: 10000
}]
};
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'
}
}]
};
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
}
}]
};
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
}
]
};
Check logs for errors:
pm2 logs my-app --err --lines 50
Not all apps work in cluster mode. Ensure:
# 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
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.
VexaNode hosting works perfectly with PM2, providing the reliable infrastructure your Node.js applications need.
Join thousands of satisfied users and experience the VexaNode difference today.
View Plans