NGINX Reverse Proxy for Node.js app

There are probably a million ways to set up your node.js application on a remote server. I know because I have been down the rabbit hole looking for answers for this seemingly simple task. While I believe that there is no “right” or “wrong” way to go about this, my current go-to approach to set up a remote node.js application is based on nginx. Here are the details.

The Node Server

First the node.js application. Nothing fancy here. Just an express server with a health check endpoint. 

const express = require('express');
const app = express();
const port = 3000;

app.get('/api/alive', (req, res) => res.send('HelloWorld!'));
app.listen(port, () => console.log('Node app listening on port ${port}!'));

Save the above code snippet to an index.js file, run it using the command node index.js , and access http://localhost:3000/api/alive to verify that all is well with your brand new server.

Now lets assume for some reason you want this app to run on an imaginary remote server located at The simplest, fastest, and (probably the dumbest) way would be to tunnel in, copy the index.js file to the server , install node.js and then run it using the command node index.js.

 Accessing would show that your app is indeed alive but its life-span will be just as much as the terminal you ran the above command in. Extremely undesirable for a node.js application. We clearly need a better alternative.


PM2 is a production ready, cross-platform node.js process manager. It does a lot of things but what we are interested in right now is its ability to keep a node.js process alive forever. To install, ssh into your server and execute the command:

npm install pm2 -g

To run your application using pm2:

pm2 start path/to/index.js --name <app_name>

Your app is now daemonized, monitored and kept alive forever. Life is good. 


More on pm2 usages can be found here.


At this point, your node.js app is up and running (seemingly forever), and is managed by a production ready process manager. You can call it a day and be done with your server and no one would blame you. Life is indeed good. But.. it can be better.

Enter nginx. Nginx is a battle-tested, open-source web-server/load-balancer/reverse-proxy, and we are going to stick it in-front of our node.js app. Several discussions as to why this might be a good idea can be found here.

Install nginx

Lets start by executing the following sequence of commands and actions to install nginx on your server:

 # downloads the key used to sign NGINX packages and adds it to apt
 sudo wget
 sudo apt-key add nginx_signing.key

 sudo nano /etc/apt/sources.list

 # add these lines to sources.list
 deb   xenial nginx
 deb-src   xenial nginx

 # installs nginx
 sudo apt-get update
 sudo apt-get install nginx

 # start nginx
 sudo nginx

 # verify NGINX is up and running
 curl -I
 HTTP/1.1 200 OK

More details on the above installation steps can be found here.

Reverse proxy configuration

The next step is to configure nginx to act as a reverse proxy so that any request intended for your node.js API is treated as such. 

This can be accomplished by either editing the nginx master configuration available at /etc/nginx/nginx.conf, or by including your own config file within the /etc/nginx/conf.d/ directory. The latter is usually the recommended approach hence go ahead and add the following configuration details to /etc/nginx/conf.d/myNodeApp.conf :

server {
   listen 80;
   listen [::]:80;
   location /api {
     proxy_pass http://localhost:3000;

This configuration simply specifies the listening port and instructs nginx to proxy any request from with the path prefix api, to port 3000 on the same server where our node.js application is up and running.

Save the conf file at /etc/nginx/conf.d/myNodeApp.conf and reload your nginx server for the changes to take effect. Your node.js application should now be accessible at via your nginx reverse proxy. 

Life is good.