Managing Node.js Processes in Production with PM2

I've been running Node.js apps in production for years, and if you're not using PM2, you're doing it wrong. PM2 is a process manager that keeps your Node.js applications running, restarts them when they crash, and handles all the operational headaches you don't want to deal with manually.
CloudPanel makes server management easier, but it doesn't handle your Node.js processes for you. That's where PM2 comes in.
What PM2 Actually Does
PM2 is a daemon process manager. It runs your Node.js apps in the background, monitors them, and restarts them if they die. It also handles logs, lets you scale to multiple instances, and persists your process list across server reboots.
Without PM2, when your app crashes (and it will crash), it stays crashed until you manually restart it. With PM2, it restarts automatically. That's the difference between waking up to angry customer emails and sleeping through the night.
Installing PM2
Install it globally with npm:
npm install -g pm2
That's it. PM2 is now available system-wide.
Essential PM2 Commands
Here are the commands you'll use every day:
Starting Applications
# Start a single app
pm2 start app.js
# Start with a custom name
pm2 start app.js --name "my-api"
# Start with environment variables
pm2 start app.js --name "my-api" --env production
Checking Status
# List all running processes
pm2 list
# Get detailed info about all processes
pm2 status
Restarting Applications
# Restart a specific app
pm2 restart my-api
# Restart all apps
pm2 restart all
# Reload (zero-downtime restart)
pm2 reload my-api
The difference between restart and reload matters. Restart kills the process and starts it again. Reload does a graceful restart without downtime if your app handles SIGINT properly.
Viewing Logs
# View logs for all apps
pm2 logs
# View logs for a specific app
pm2 logs my-api
# View logs in real-time (like tail -f)
pm2 logs --lines 100
Stopping and Deleting
# Stop an app (keeps it in the process list)
pm2 stop my-api
# Delete an app (removes it completely)
pm2 delete my-api
# Stop and delete everything
pm2 delete all
Surviving Server Reboots
This is where most people mess up. By default, PM2 processes don't survive server reboots. You need to configure startup scripts.
Setting Up Auto-Start
Run this command to generate startup scripts:
pm2 startup
PM2 will detect your system (systemd, upstart, etc.) and give you a command to run. It looks something like:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u your-username --hp /home/your-username
Copy and run that exact command. This creates a system service that starts PM2 when your server boots.
Saving Your Process List
After setting up startup, you need to save your current process list:
pm2 save
This creates a dump file that PM2 uses to resurrect your processes after a reboot. Run pm2 save every time you add or remove applications.
Testing the Setup
Reboot your server and check if your processes come back:
sudo reboot
# Wait for server to come back up
pm2 list
If your processes aren't there, you probably skipped the pm2 save step or didn't run the startup command properly.
Configuration Files
For complex setups, use an ecosystem file instead of command-line arguments:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'my-api',
script: 'app.js',
instances: 2,
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production',
PORT: 3000
}
}]
}
Start it with:
pm2 start ecosystem.config.js --env production
CloudPanel Integration
CloudPanel runs as the clp user, but you'll typically want to run your Node.js apps as your site user. Make sure you:
- Install PM2 as the correct user
- Set up the startup script under that user
- Configure your reverse proxy in CloudPanel to point to your Node.js app
Your reverse proxy configuration in CloudPanel should point to http://127.0.0.1:3000 (or whatever port your app uses).
The Reality Check
PM2 isn't perfect. It adds complexity, uses memory, and occasionally has issues with file watching in development. But in production, it's essential. I've seen too many Node.js apps running with nohup node app.js & or inside screen sessions. Don't be that person.
Set up PM2 properly once, and your Node.js apps will keep running regardless of crashes, deployments, or server reboots. It's the difference between professional and amateur hour.
Tagged
If this post was useful, consider buying me a coffee ☕ with ₿itcoin — no account needed, any amount welcome.