Deploying Node.js Applications with PM2

Posted on Apr 15, 2015


Guest post: Today’s post will feature a tutorial for deploying Node.js apps on Digial Ocean by Raghuvir Kasturi, a multi-talented full stack engineer.


Deploying Node.js applications is hard

Ask anyone who’s jumped on the self-taught hacker bandwagon, gone through an online tutorial or two and then attempted to get their basic ToDo app to actually run on anything but localhost.

This tutorial walks through setting up a very basic push-to-deploy workflow using PM2, nginx & GitHub. This workflow has been tested on a Digital Ocean 14.04 box, but could be adapted for other systems with some tweaking.

What is PM2?

From the official repo:

PM2 is a production process manager for Node.js applications with a built-in load balancer.

PM2 gives you an accessible and comprehensive toolkit to deploy and manage your Node.js applications in a production environment. While this tutorial focuses on the deployment arm of PM2, I would encourage you to spend some time looking through the other features; the CLI is extremely user-friendly.

What you’ll need

You’ll need the following (or some variants thereof):

  • A VPS that you can SSH into (I use an Ubuntu 14.04 box provided by Digital Ocean).
  • A GitHub account

I use a Mac as my personal computer, but everything going forward should work on any *NIX OS. If you use Windows you might have to Google around for hacks.

Initial setup

Node.js/npm

The first thing to do is make sure both your computer and your server have Node.js (and npm) installed. There are numerous ways to do this, depending on your OS and requirements. The easiest way to get it is via their website. If you need to install it via CLI – on your server – here’s a good guide.

Once that’s done, you’ll need PM2 installed on both your personal computer and your server.


If you need to update PM2 on either your computer or the server, you can install the latest at any point using

and then run

This will update the in-memory PM2 to the latest installed version.

GitHub

For this tutorial, we’ll be using GitHub as the DVCS of choice. This means your workflow will be something similar to this

  • Work on your local copy of your code and test/run locally until you’re satisfied.
  • Once satisfied, push up to GitHub.
  • Use PM2 to deploy your latest version from GitHub.

This means your server needs to have SSH access to GitHub in order to pull your code and restart the server with the changes. You’ll need to create a new SSH key on your server and add the public key to GitHub. I’ve posted a guide on working with SSH keys that may be of help if you’re unfamiliar with them.

nginx

To serve our new Node app, we’re going to use nginx as the front-end server which will then proxy requests to our Node server. Nginx provides a lot of tools out of the box that we can use to avoid unnecessary stress on our Node server, such as GZIP encoding, static file serving, and HTTP caching.

Your server will need to have nginx installed, and the easiest way to do this is by using the OS’s package manager. For example, on Ubuntu 14.04

Make sure it’s working by checking your IP or hostname in a browser. If all went well, you should see the default nginx landing page.

Default Nginx Landing Page

Once you have it installed, you’ll need to set up the proxy configuration for your Node.js server.

A sample config file for your app looks something like this (and would site inside /etc/nginx/sites-available)

You should change your proxy_pass to whatever host/port your Node.js server is running on.

Deploy

Now that you’ve got everything set up, you’re ready to deploy! We’re going to deploy a simple Express app.

app.js

PM2 uses a special file called ecosystem.json as its configuration file. Similar to npm, PM2 gives you a way to create one via the CLI.

This will generate a new ecosystem.json in your current folder. We’ll modify it a bit to suit our (very basic) needs.

This allows you to have multiple deployment options based on your needs (dev, staging, production), all of which are managed with a single ecosystem file.

Once this is done, initialise the folders on your server

where environment is the deployment environment. It must be defined in your ecosystem.json for the setup to work. For example

Once this is done, go ahead and deploy!

This will deploy your code, install all dependencies, and run your Node.js server. You may have to restart nginx for the proxy to take effect, but if all has gone well, you should see your shiny new app if you navigate to your host or IP in a browser!

Closing thoughts

pm2 deploy

PM2’s deploy allows you to revert changes, update, list all the deploy commits, and much more – giving you a lot of control if things break.

ecosystem.json

If you get errors with the “post-deploy” saying it couldn’t find the npm, node, or pm2 commands, you may have to supply absolute paths for the executables, or make sure your $PATH variable for the user running the Node app is set up correctly.

Happy deploying!


About Raghu

raghuRaghuvir Kasturi is a software engineer with a background in physics, based out of Bangalore, India. Raghu is interested in designing and building scalable and modular systems that can be leveraged on the modern multi-device web via meaningful user experiences. His current focus is on high impact data visualisations and build & deployment strategies for web & mobile applications. You can find Raghu’s writings here

Submit a Comment

Your email address will not be published. Required fields are marked *