November 04, 2014

Node Process Management with PM2

Manage NodeJS processes with PM2

In a previous edition, I wrote about using Supervisord to watch and manage processes. In this edition, we'll cover process monitoring for NodeJS applications using PM2.

PM2 is a process manager for NodeJS applications. One of its nicer features is automatic use of Node's Cluster API. PM2 gives your application the ability to be run as multiple processes, typically without having to modify it.

In this edition, we'll cover installing, configuring and using PM2.

Install

I'll assume we're using Ubuntu 14.04.

The first thing we need to do is install Node. This can be done easily using Chris Lea and Nodesource's packaging for NodeJS.

curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install -y nodejs

Once that's installed, we can install PM2 globally. If you're using NVM, you likely won't use sudo here:

sudo npm install pm2 -g --unsafe-perm

Web Interface (JSON API)

PM2 comes with a web interface, in the form of a JSON API. We can start that by running the following command:

pm2 web

This listens on all networks on port 9615. The web interface is actually a monitored process. We can inspect any monitored processed like so:

# List processes monitored
pm2 list

# See "tail" style log output of all logs output from watched processes
pm2 logs

# Clear all logs
pm2 flush

# List process 0 (the web interface in this case)
pm2 desc 0

# Monitor processes and system usage
pm2 monit

Here's the web interface:

pm2 web interface json api

Monitoring A Sample Application

Similar to the Supervisord edition, we need a sample application to monitor. In this case, we'll use a quick and dirty Node application, listening over HTTP for new requests.

File app.js:

var http = require('http');

function serve(ip, port)
{
     http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'text/plain'}); // Return a 200 response
        res.write(JSON.stringify(req.headers));             // Respond with request headers
        res.end("\nServer Address: "+ip+":"+port+"\n");     // Let us know the server that responded
    }).listen(port, ip);
    console.log('Server running at http://'+ip+':'+port+'/');
}

serve('0.0.0.0', 9000);

Running the Application

Running an application with PM2 is fairly straight forward:

pm2 start app.js --name "myapp" -i max

Let's cover this command:

  • start app.js - Run and monitor application
  • --name - Name the application, so we can refer to it in other commands
  • -i max - Run multiple processes of the application. PM2 will run one process per CPU core. It will also attempt to load balance requests between the running processes.

We named the process myapp, which we can use in other commands:

# Reload and restart the application
pm2 reload myapp

# Stop the application
pm2 stop myapp

# Remove myapp from PM2
pm2 delete myapp

There are a few other commands you can use as well, such as gracefulReload, useful for closing all existing connections before restarting.

Now we can see both the web interface and our application being monitored:

pm2 list

Start on Boot

PM2 is a process monitor, but it needs some monitoring itself! We want it to start on system boot. To do so, we can use an operating system's various boot mechanisms.

PM2 has tools to make this very easy for us! It can create startup configurations for Ubuntu, CentOS, Gentoo and anything supporting Systemd.

If you run the command pm2 startup, you'll likely be told you need to run the command as root, and get a command specifically for your operating system. For example, on Ubuntu, I did the following:

# Run without "root", gives handy message
$ pm2 startup ubuntu
[PM2] You have to run this command as root
[PM2] Execute the following command :
[PM2] sudo env PATH=$PATH:/usr/bin pm2 startup ubuntu -u vagrant

That tells me the exact command to run!

# Run the given command with root:
$ sudo env PATH=$PATH:/usr/bin pm2 startup ubuntu -u vagrant

This setup Ubuntu to start PM2 on boot. Once that's done, run pm2 save to have PM2 save the currently monitored processes. It will restart these when the system boots back up.

$ pm2 save
[PM2] Dumping processes

The dump command will save information to the /home/USER/.pm2/dump.pm2 file. The data is saved as JSON and is used to configure running processes on startup.

The .pm2 directory contains other files as well, including logs pids files.

Pid files are just files with a process id set in its contents.

After this is set and you restart your server, you should see the processes up and running. Here's what the pm2 monit command looks like, just restarting my server:

pm2 monitor

All Topics