PM2 Complete Guide | Production Process Manager for Node.js
이 글의 핵심
PM2 is a production process manager for Node.js. It provides clustering, monitoring, logging, zero-downtime reloads, and automatic restarts for reliable Node.js deployments.
Introduction
PM2 is a production-grade process manager for Node.js applications. It keeps your app running 24/7, handles crashes, enables clustering, and provides monitoring and logging.
Why PM2?
Without PM2:
node app.js
# App crashes → stays down
# Server restarts → app doesn't start
# 1 process → can't use all CPU cores
With PM2:
pm2 start app.js
# App crashes → auto-restart
# Server restarts → app auto-starts
# Cluster mode → uses all CPU cores
# Built-in monitoring and logs
1. Installation
# Global install (recommended)
npm install -g pm2
# Or with yarn
yarn global add pm2
# Verify
pm2 --version
2. Basic Usage
# Start app
pm2 start app.js
# Start with name
pm2 start app.js --name my-app
# Start with watch (auto-reload on file change)
pm2 start app.js --watch
# Start with environment
pm2 start app.js --env production
# List all processes
pm2 list
# Stop app
pm2 stop my-app
# Restart app
pm2 restart my-app
# Delete app from PM2
pm2 delete my-app
# Stop all
pm2 stop all
# Restart all
pm2 restart all
# Delete all
pm2 delete all
3. Cluster Mode
# Start in cluster mode (uses all CPU cores)
pm2 start app.js -i max
# Start with specific number of instances
pm2 start app.js -i 4
# Scale up/down
pm2 scale my-app 8 # Scale to 8 instances
pm2 scale my-app +2 # Add 2 more instances
pm2 scale my-app -2 # Remove 2 instances
Example: Cluster-Ready Express App
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send(`Hello from process ${process.pid}`);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}, PID: ${process.pid}`);
});
# Start 4 instances
pm2 start app.js -i 4
# Each request handled by different process
curl http://localhost:3000 # Process 1234
curl http://localhost:3000 # Process 1235
curl http://localhost:3000 # Process 1236
curl http://localhost:3000 # Process 1237
4. Ecosystem File
# Generate ecosystem file
pm2 ecosystem
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'api',
script: './app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000,
},
env_production: {
NODE_ENV: 'production',
PORT: 8080,
},
error_file: './logs/err.log',
out_file: './logs/out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
max_memory_restart: '500M',
watch: false,
ignore_watch: ['node_modules', 'logs'],
},
{
name: 'worker',
script: './worker.js',
instances: 2,
exec_mode: 'cluster',
cron_restart: '0 0 * * *', // Restart at midnight
},
],
};
# Start from ecosystem file
pm2 start ecosystem.config.js
# Start with specific environment
pm2 start ecosystem.config.js --env production
# Restart all apps in ecosystem
pm2 restart ecosystem.config.js
# Stop all apps in ecosystem
pm2 stop ecosystem.config.js
5. Monitoring
# Real-time monitoring
pm2 monit
# Show detailed info
pm2 show my-app
# Show logs
pm2 logs
# Show logs for specific app
pm2 logs my-app
# Show only errors
pm2 logs --err
# Flush all logs
pm2 flush
# Dashboard (web UI)
pm2 plus
6. Logging
# View logs
pm2 logs
# View last 100 lines
pm2 logs --lines 100
# Real-time logs
pm2 logs --raw
# JSON logs
pm2 logs --json
# Log file locations
~/.pm2/logs/app-out.log # stdout
~/.pm2/logs/app-error.log # stderr
Custom Log Files
// ecosystem.config.js
module.exports = {
apps: [{
name: 'api',
script: './app.js',
error_file: './logs/api-error.log',
out_file: './logs/api-out.log',
merge_logs: true,
log_date_format: 'YYYY-MM-DD HH:mm:ss',
}],
};
Log Rotation
# Install PM2 log rotate
pm2 install pm2-logrotate
# Configure rotation
pm2 set pm2-logrotate:max_size 10M # Max size per file
pm2 set pm2-logrotate:retain 7 # Keep 7 files
pm2 set pm2-logrotate:compress true # Compress old logs
pm2 set pm2-logrotate:rotateInterval '0 0 * * *' # Rotate daily
7. Auto-Restart on Server Reboot
# Save current PM2 process list
pm2 save
# Generate startup script
pm2 startup
# Follow instructions to run the generated command
# Example: sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u user --hp /home/user
# Now PM2 will auto-start on server reboot
# To remove startup script
pm2 unstartup
8. Zero-Downtime Reload
# Reload app (zero downtime, cluster mode only)
pm2 reload my-app
# Graceful reload (waits for existing requests)
pm2 reload my-app --wait-ready
# Restart (downtime)
pm2 restart my-app
Graceful Shutdown
// app.js
const express = require('express');
const app = express();
const server = app.listen(3000);
// Listen for shutdown signal
process.on('SIGINT', () => {
console.log('Received SIGINT, graceful shutdown...');
server.close(() => {
console.log('Closed all connections');
process.exit(0);
});
// Force shutdown after 30s
setTimeout(() => {
console.error('Forced shutdown');
process.exit(1);
}, 30000);
});
9. Environment Variables
# Set environment variables
pm2 start app.js --env production
# Or via ecosystem file
pm2 start ecosystem.config.js --env production
// ecosystem.config.js
module.exports = {
apps: [{
name: 'api',
script: './app.js',
env: {
NODE_ENV: 'development',
PORT: 3000,
DB_HOST: 'localhost',
},
env_production: {
NODE_ENV: 'production',
PORT: 8080,
DB_HOST: 'prod-db.example.com',
},
env_staging: {
NODE_ENV: 'staging',
PORT: 8080,
DB_HOST: 'staging-db.example.com',
},
}],
};
10. TypeScript Support
# Install ts-node
npm install -D ts-node typescript
# Start TypeScript app
pm2 start app.ts --interpreter ts-node
# Or compile first (recommended for production)
npm run build
pm2 start dist/app.js
// ecosystem.config.js for TypeScript
module.exports = {
apps: [{
name: 'api',
script: './src/app.ts',
interpreter: 'ts-node',
watch: ['src'],
ignore_watch: ['node_modules', 'dist'],
env: {
TS_NODE_PROJECT: './tsconfig.json',
},
}],
};
11. Memory Management
// ecosystem.config.js
module.exports = {
apps: [{
name: 'api',
script: './app.js',
max_memory_restart: '500M', // Restart if memory exceeds 500MB
max_restarts: 10, // Max restarts within restart_delay
min_uptime: '10s', // Min uptime before considered stable
restart_delay: 4000, // Delay between restarts (ms)
}],
};
12. Monitoring with PM2 Plus
# Link to PM2 Plus (free tier available)
pm2 plus
# Or with specific bucket
pm2 link <secret_key> <public_key>
# Disconnect
pm2 unlink
PM2 Plus provides:
- Real-time dashboard
- Error tracking
- Transaction tracing
- Custom metrics
- Email/Slack alerts
13. Docker Integration
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm install -g pm2
EXPOSE 3000
CMD ["pm2-runtime", "ecosystem.config.js"]
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
restart: unless-stopped
14. Best Practices
1. Use Ecosystem File
# Good: version-controlled config
pm2 start ecosystem.config.js
# Bad: CLI flags (hard to reproduce)
pm2 start app.js -i 4 --max-memory-restart 500M --env production
2. Cluster Mode for Web Servers
module.exports = {
apps: [{
name: 'web-server',
script: './app.js',
instances: 'max', // Use all CPUs
exec_mode: 'cluster', // Enable clustering
}],
};
3. Fork Mode for Workers
module.exports = {
apps: [{
name: 'queue-worker',
script: './worker.js',
instances: 1, // Single instance
exec_mode: 'fork', // Fork mode
}],
};
4. Log Rotation
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
5. Startup Script
pm2 save
pm2 startup
15. Common Commands
# Status
pm2 status # List all processes
pm2 list # Same as status
pm2 show <app> # Detailed info
# Logs
pm2 logs # All logs
pm2 logs <app> # App logs
pm2 logs --lines 200 # Last 200 lines
pm2 flush # Clear logs
# Control
pm2 start <app>
pm2 stop <app>
pm2 restart <app>
pm2 reload <app> # Zero-downtime (cluster only)
pm2 delete <app>
# Monitoring
pm2 monit # Real-time monitor
pm2 plus # Web dashboard
# Maintenance
pm2 save # Save process list
pm2 startup # Auto-start on boot
pm2 resurrect # Restore saved processes
pm2 update # Update PM2 in-memory
pm2 reset <app> # Reset restart counter
16. Real-World Example
// ecosystem.config.js
module.exports = {
apps: [
// API server (cluster mode)
{
name: 'api',
script: './dist/api/server.js',
instances: 'max',
exec_mode: 'cluster',
env_production: {
NODE_ENV: 'production',
PORT: 8080,
DB_HOST: process.env.DB_HOST,
REDIS_URL: process.env.REDIS_URL,
},
error_file: './logs/api-error.log',
out_file: './logs/api-out.log',
max_memory_restart: '1G',
min_uptime: '10s',
max_restarts: 10,
},
// Background worker (fork mode)
{
name: 'worker',
script: './dist/worker/index.js',
instances: 2,
exec_mode: 'fork',
env_production: {
NODE_ENV: 'production',
REDIS_URL: process.env.REDIS_URL,
},
error_file: './logs/worker-error.log',
out_file: './logs/worker-out.log',
max_memory_restart: '500M',
cron_restart: '0 3 * * *', // Restart at 3 AM daily
},
// Cron job
{
name: 'cleanup',
script: './dist/jobs/cleanup.js',
instances: 1,
cron_restart: '0 0 * * *', // Run at midnight
autorestart: false,
},
],
};
# Deploy
npm run build
pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup
# Update
git pull
npm run build
pm2 reload ecosystem.config.js --env production
Summary
PM2 is essential for Node.js production:
- Process management with auto-restart
- Cluster mode for multi-core scaling
- Zero-downtime reloads
- Monitoring and logging
- Startup scripts for auto-start
Key Takeaways:
- Always use PM2 in production
- Enable cluster mode for web servers
- Configure log rotation
- Set up startup script
- Use ecosystem file for config
Next Steps:
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete PM2 guide for Node.js production deployment. Learn process management, clustering, monitoring, logging, zero-do…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- dotenv Complete Guide | Environment Variables in Node.js
- Winston Complete Guide | Node.js Logging Library
- C++ Facade Pattern Complete Guide
Keywords Covered in This Article (Related Search Terms)
This article covers PM2, Node.js, DevOps, Production, Process Manager, Deployment.