How To Deploy NodeJS Apps With PM2 & NGINX In Cluster Mode On Production Environment
Tags: node, nginx, pm2, devops
Published: 2020-05-20 20:36:23

## What is Process Manager?

Process Manager is a special program design to effectively manage server process and take benefit of server resources. It's useful to keep application online and restart on failure.

Process Manager is also useful for clustering, logging and monitoring the application. Process Managers make it possible to demonize the application so it will be running in background as a service.

## Prerequisites:
In this tutorial we assume that you have following setup:
* Ubuntu server and a user with root / sudo privileges
* All the necessary package installed to run simple NodeJS App


## Which Process Manager?
There are multiple Process Manager available, as listed below but in this tutorial we will be focusing on **PM2**.

* [PM2](https://pm2.keymetrics.io/)
* [StrongLoop PM](https://strong-pm.io/)
* [Forever](https://github.com/foreversd/forever)

## Why PM2?
Following are the complete features set of PM2

![PM2 Features](https://i.imgur.com/4yXiyrt.png)

## Install Process Manager:

 Use `npm` to install the pm2 globally so it will available system-wide for use

``` bash
$ sudo npm i pm2 -g
```
Now let start our NodeJS app using `pm2 start` command

First change the directory to our node application directory

``` bash
$ cd /opt/hello-pm2/
$ pm2 start app.js --name Hello -i 2 --watch
```
It will also register our app in the process list of PM2, which you can see in the output of the above command

![Output of PM2 Start](https://i.imgur.com/OaLuQGO.png)

## PM2 as a service:

PM2 will take care of all the application running under it and will restart automatically if the application killed or crash, but what if the system boot or reboot? PM2 has answer for this, PM2 provide an easy way to start PM2 as a system service in `systemd`.

The `startup` command generate and configure a PM2 startup script.

```bash
$ pm2 startup
```

Now to setup the startup script copy/paste the last line from the output or earlier command,

```bash
[PM2] Init System found: systemd
meswapnilwagh
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u meswapnilwagh --hp /home/meswapnilwagh
```

Run the command to setup PM2 to start on boot/reboot 

``` bash
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u meswapnilwagh --hp /home/meswapnilwagh
```

## Basic PM2 Commands:

Just like all other command line utility, PM2 also comes with bundle of subcommands which are helpful to manage application running under PM2

### Start Application in cluster

To start application in cluster mode you can use `-i` flag and specify the number of instances you want to run you can also use `--name` flag to name your process.

``` bash
sudo pm2 start /opt/hello-pm2/app.js --name Hello -i 4
```

### Stop Application 

``` bash
sudo pm2 stop Hello
```

### Restart Application

``` bash
sudo pm2 restart Hello
```

### List Applications

``` bash
sudo pm2 list
```

### Monitor Application Process

``` bash
sudo pm2 monit
```

For more usage of PM2 please refer [PM2 quick start](https://pm2.keymetrics.io/docs/usage/quick-start/).

## [NGINX](https://www.nginx.com) As Reverse Proxy :

Till now we configure PM2 and running our node app in cluster seems all good, but are you still ready for production? How can you get rid of that port in your URL? Answer to all your question is Nginx (Engine-X).

### What is NGINX? 

Officially, Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache. 

Best practice to deploy NodeJS application in production, is by using Nginx as reverse proxy to route the web client's requests to appropriate node process.

### Install NGINX

Use following command to install Nginx on Ubuntu

``` bash
$ sudo apt-get update
$ sudo apt-get install nginx
```

### Configure NGINX 

Open the nginx default site config file:

``` bash
$ sudo nano /etc/nginx/sites-available/default
```

Now add below configuration in the file (You can take backup of original file for safer side)

```bash
server {
  listen       80;
  server_name  mycooldomain.com;

  location / {
    proxy_pass http://localhost:4000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}
```

As you can see the nginx listening on http://mycooldomain.com and the `location /` block take care of the incoming request and forwarding to NodeJS application.

Save the file and restart nginx,

```bash
$ sudo service nginx restart
```

Now open your browser and navigate to http://mycooldomain.com, you can see how node app is being served without using any port in URL.

**Congratulations**!! You had successfully deployed NodeJS app on production using PM2 and Ngnix.

Hope you find this tutorial helpful. Don't forget to share if its really help you. For any query please DM at [Swapnil Wagh](https://twitter.com/meswapnilwagh)