PM2 is a production-grade process manager for Node.js applications that handles automatic restarts on crashes, log aggregation, clustering, and startup script generation for Linux init systems including systemd. Unlike running Node.js directly with node app.js, PM2 keeps your application alive across failures and server reboots without writing custom systemd unit files for every project. On RHEL 8, PM2 integrates cleanly with systemd to provide reliable application lifecycle management. This tutorial covers installation, core process management commands, startup configuration, and using ecosystem.config.js for managing multiple applications.
Prerequisites
- RHEL 8 server with a sudo-capable user
- Node.js installed (via AppStream or NodeSource — see the Node.js installation guide)
- npm available alongside Node.js
- A Node.js application to deploy (an Express app is used in this tutorial)
Step 1 — Install PM2 Globally
Install PM2 as a global npm package so the pm2 command is available system-wide.
sudo npm install -g pm2
# Verify the installed version
pm2 --version
Create a simple test application if you do not already have one:
mkdir -p ~/myapp && cd ~/myapp
npm init -y
npm install express
cat > app.js < res.json({ status: 'running', manager: 'PM2' }));
app.listen(3000, () => console.log('App listening on port 3000'));
EOF
Step 2 — Start and Manage Processes with PM2
The pm2 start command launches your application and registers it with the PM2 daemon. Assign a name with --name to make subsequent commands easier to use.
cd ~/myapp
# Start the application
pm2 start app.js --name myapp
# View all running processes
pm2 list
# View detailed info for a specific process
pm2 show myapp
# Tail live logs
pm2 logs myapp
# View last 100 log lines
pm2 logs myapp --lines 100
Step 3 — Control Running Processes
PM2 provides intuitive commands for restarting, stopping, and removing processes. Restarting with --update-env picks up any changed environment variables without a full stop-start cycle.
# Graceful restart (zero-downtime when cluster mode is used)
pm2 restart myapp
# Restart and reload updated environment variables
pm2 restart myapp --update-env
# Stop the process (keeps it in the list, does not start on reboot)
pm2 stop myapp
# Remove the process from PM2 entirely
pm2 delete myapp
# Reload all running processes (useful after deploying new code)
pm2 reload all
Step 4 — Generate a systemd Startup Script
The pm2 startup command generates a systemd unit that starts the PM2 daemon at boot, which in turn starts all processes saved with pm2 save. Run the command first to get the exact sudo command tailored to your system.
# Generate the startup command (outputs a sudo command — copy and run it)
pm2 startup systemd -u youruser --hp /home/youruser
PM2 will print a command like the one below. Copy it exactly and run it:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2
startup systemd -u youruser --hp /home/youruser
Then save the current process list so PM2 restores it on reboot:
pm2 save
Step 5 — Use ecosystem.config.js for Multi-App Management
The ecosystem.config.js file is PM2’s declarative configuration format. It lets you define all your applications, their environment variables, cluster settings, and log paths in one file — ideal for managing multiple services on a single server.
cat > ~/ecosystem.config.js << 'EOF'
module.exports = {
apps: [
{
name: 'api',
script: '/home/youruser/myapp/app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000,
},
env_production: {
NODE_ENV: 'production',
PORT: 3000,
},
log_date_format: 'YYYY-MM-DD HH:mm:ss',
error_file: '/home/youruser/logs/api-error.log',
out_file: '/home/youruser/logs/api-out.log',
},
{
name: 'worker',
script: '/home/youruser/myworker/worker.js',
instances: 1,
autorestart: true,
},
],
};
EOF
# Start all apps defined in the ecosystem file with production env
pm2 start ~/ecosystem.config.js --env production
# Save the updated process list
pm2 save
Step 6 — Monitor Applications with PM2
PM2 includes a built-in real-time monitoring dashboard and integrates with PM2 Plus for remote monitoring and alerting.
# Terminal-based real-time dashboard (CPU, memory, logs, restarts)
pm2 monit
# Show aggregated metrics for all processes
pm2 status
# Show metrics including uptime and restart count
pm2 info myapp
# Flush all log files
pm2 flush
# Rotate logs (requires pm2-logrotate module)
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7
Conclusion
PM2 transforms Node.js application management on RHEL 8 from fragile manual processes into a robust, production-ready workflow. With automatic restarts, systemd integration via pm2 startup, centralized logging, and the ecosystem.config.js format for managing multiple services, PM2 handles the operational concerns that let you focus on application development. The cluster mode (instances: 'max') also allows you to take advantage of all available CPU cores with zero additional configuration.
Next steps: Setting Up Nginx as a Reverse Proxy for Node.js on RHEL 8, How to Manage Node.js Versions with NVM on RHEL 8, and Monitoring Node.js Applications with PM2 Plus and Grafana on RHEL 8.