Photo by Joshua Aragon on Unsplash

PM2: Production-Ready Nodejs Applications in Minutes

Amir G.
The Startup
Published in
6 min readJan 30, 2021

--

Contents

  • What is PM2
  • Installation
  • Example Application Setup
  • Application Management with PM2
  • Why Use PM2
  • PM2 Use Cases
  • PM2 in Development
  • PM2 Environment Variables
  • PM2 Error Logs
  • PM2 in Production
  • What is Blue-Green Deployment?
  • How can Blue-Green Deployment be Implemented Using PM2?
  • Conclusion

What is PM2?

In this article, we are going to explore the PM2 process manager. We will start with an overview of how to install it and use it to get a basic Nodejs application ready for production within minutes. Then we will go on to see some of the benefits of using PM2. Finally, we will take a look at some specific PM2 use cases in the development and production stages of application development. This article is meant to be a reference and a tutorial, so feel free to code along to get practical, hands-on experience with PM2.

Installation

Let’s get started by first installing PM2 using a package manager from the command line:

$ npm i pm2 -g

or

$ yarn global add pm2

Example Application Setup

We are going to be using a basic express application in order to demonstrate PM2’s application management capabilities:

$ npm create -y

$ npm i express --save

$ touch index.js

copy the following code into index.js:

const express = require('express');const app = express();const PORT = process.env.PORTapp.get('/',(req,res) => {
res.send("Hello World!\n");
})
app.listen(PORT,() => {
console.log(`server is running on port ${PORT}`);
})

We are now ready to run and manage our application with PM2!

Application Management

In order to run and manage our application with PM2, we need to configure it, first. PM2 configuration files can be in a variety of formats, including Javascript, JSON and YAML. We will be using a JSON file in this walk-through. Begin by running the following command:

$ pm2 ecosystem

This will automatically generate a config file for you by the name of ecosystem.config.js:

module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],
deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};

Make sure that this file is in the root of your application directory. As you can see above, PM2 is highly configurable, with many advanced options such as deployment hooks. For a detailed list of configuration choices, refer to the PM2 configuration docs

The only thing left to do is to add a new environment variable to configure the port on which the application shall run:

module.exports = {
apps : [{
script: 'index.js',
watch: '.',
// add the port as an environment variable
env: {
PORT: 8080
}
...

Start the application with PM2 using the following command:

$ pm2 start ecosystem.config.js

Voila! After a few seconds, the application is live and listening for requests:

$ curl localhost:8080
Hello World!

Why Use PM2

Application managers are an essential utility in the tool set of every developer and operations engineer. They allow for quick and convenient application configuration so that all it takes to get an application ready for production or development is a few quick commands. Furthermore, they make managing services and processes scalable. Although there are other similar solutions available, such as Docker, Kubernetes, and Linux Containers, the PM2 application manager has been developed with Nodejs applications in mind.

PM2 Github Repository

Another thing to keep in mind is that the PM2 application manager is a popular project with an active community of users and developers. This means that the project has been time tested and hardened with real world work-loads. This results in a more secure application manager.

Use Cases

Let’s take a look at a few different ways the PM2 application manager can add value to our development and production environments.

PM2 in Development

Using PM2 in development can provide some advantages. It can be used to develop and test multiple versions of the same application at the same time. Also, hot reloading can be configured using the watch parameter or by using another program such as nodemon. PM2’s approach to environment variables and log files provides convenience for developers.

PM2 Environment Variables

In development, PM2 allows for the convenient isolation of development and production environment variables, all defined in a single configuration file. Let’s return to the ecosystem.config.js file we created earlier:

module.exports = {
apps : [{
script: 'index.js',
watch: '.',
// add development environment variables
env_development: {
PORT: 8080
},
// add production environment variables
env_production: {
PORT: 8081
}
...

It is now possible to indicate which environment variables should be used with a single command:

$ pm2 start ecosystem.config.js --env development

PM2 Error Logs

The PM2 error logs can help track down bugs in development. They are accessible via the command line:

$ pm2 logs

The default location of PM2 log files is in the /.pm2/logs directory that PM2 automatically creates in the user’s home directory.

PM2 in Production

Let’s finish off with a look at how to implement a blue-green deployment model to allow patching an application in production with minimal downtime using only the PM2 application manager.

What is Blue-Green Deployment?

Blue-Green Deployment Model Diagram

Blue-green deployment is an application management model that includes keeping two nearly identical versions of an app available to accept traffic in production. This allows for quick recovery in case the newer of the applications fails due to unforeseen circumstances and a regression is needed, in which case, the old application is ready to accept traffic immediately. Blue-green deployment reduces downtime when an application that is in production needs to be patched for any reason.

How can Blue-Green Deployment be Implemented Using PM2?

PM2 allows us to keep multiple applications readily available for deployment. All it takes to start a stopped PM2 application is a single command. This, in conjunction with a reverse-proxy, such as Nginx, allow for a robust production setup for Nodejs applications.

Let’s begin with creating a new version of the application we were working with earlier and put it inside a different directory:

$ mkdir blue

$ mv -t blue *.json *.js node_modules

$ cp -r blue ./green

Make a change to the green version of the application in order to denote a newer version of the blue application that is to go into production with minimal downtime:

...app.get('/',(req,res) => {
res.send("Hello World, I'm the green application!!\n");
})
...

Let’s also give our application a name by adding a ‘name’ modifier in the pm2 configuration files of each of our applications to make our lives easier:

module.exports = {
apps : [{
// new modifier
name: 'green',
...

Run the old application with PM2:

$ cd blue

$ pm2 start ecosystem.config.js --env production

Now change directories to the newer version of the application in the green directory and switch the version of the application that is online to the new version of the application:

$ cd ../green

$ pm2 stop blue && pm2 start ./ecosystem.config.js --env production

In case of a regression, the blue version of the application can be reactivated with minimal downtime to allow for green to recover:

$ pm2 stop green && pm2 start blue

Conclusion:

The PM2 application manager is an ideal solution for Nodejs developers. It is robust, well documented, easy to get started with, and has a rich set of features.

--

--