How to Set up a Node.JS Application for Production Using PM2 Process Manager and Nginx as a Reverse Proxy


This article provides a walk-through on how to configure a server to handle your node.js application using the PM2 process manager and Nginx as a reverse proxy server.


Building the node.js application

For simplicity, a basic hello world app will be created. The app will simply return the ‘hello world’ response once a request is made to the server. To start, we create a folder in our directory with a file called ‘helloWorld.js’.

mkdir $HOME/hello
cd $HOME/HELLO && nano helloWorld.js

Next, we populate the file with a simple server script

#! /usr/bin/env nodejsconst http = require('http');http.createServer((req, res) => {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello World!');}).listen(4000, 'localhost');console.log('Server up and running at http://localhost:4000');

The above code simply creates a server that responds to requests with a 200 status code and content-type HTTP header. The connection ends with a ‘Hello World!’ chunk as the response. The app will listen on port 4000 using ‘localhost’ as an address. Save the file (ctrl o then enter) and exit ( ctrl x).

Executing the script

We will now have to assign an execute permission to the file, as

chmod +x $HOME/hello/helloWorld.js

To run the script, simply type the following in your terminal


The output should be visible on our browser using the URL http://localhost:4000

After verifying the response, kill the application by pressing Ctrl+C on the terminal.


If you do not see the response on the browser, ensure that the application is running, and configured to listen on the proper port (In this case, it’s 4000) and with the proper address (‘localhost’).

Time to install PM2

PM2 is an npm package that functions as a production process manager for Node.js applications. It comes with a built-in load balancer, allowing you to keep applications alive, and to reload them without encountering a downtime.

To install pm2 globally on your machine, simply enter the following in your terminal

sudo npm install pm2 -g

Next, we manage the app using pm2. To run your app, we simply run the following in terminal;

pm2 start helloWorld.js

The above will add your app to PM2’s process list of managed apps

Based on the output, PM2 basically assigns a name property as well as process id to the new process. In addition, information about the process status, memory, and CPU usage are included.

In order to get more details about your running app, you may use the command below:

pm2 show [id]

remember to replace id with the process id (in this case, it’s 0).

Should you choose to stop your running app, use the command below:

pm2 stop [id]

So far, we have assigned pm2 the task of maintaining our app in a running mode. How do we ensure that the app is always launched on system startup?

For this, we simply use the PM2 startup command to generate pm2’s startup script. This will be launched on system startup.

pm2 startup systemd


Make sure to run the command provided in your terminal output. This will basically create a systemd unit for your PM2 process manager. With this, the systemd system service manager will always bring up your service. Next, we configure the Nginx web server as a reverse proxy.

Nginx reverse proxy configuration

In order to configure the installed Nginx server as a reverse proxy, we simply: 1. create a file in the /etc/nginx/sites-available directory

sudo nano /etc/nginx/sites-available/server

Input the following in the server file created:

server {
listen 80;
location / {
#you may replace server_name value with your
#server hostname
# e.g server_name;
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;

Basically, we are setting the server in such a way that requests coming into (the server_name directive value) are directed to localhost on port 4000 (where our app is listening on).

The proxy_set_header directives are mainly used to pass vital information about the request. Also, proxy_pass specifies that the request should be forwarded to the backend server (the helloWorld app).


  • Normally, the server_name directive value should be localhost since it’s our hosts local domain name. Should you choose to change it locally like I did, simply add an entry in your /etc/hosts file: localhost mekky-mayata # replace with your desired local
# domain name
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Save the file and remember to change the server_name directive value to your chosen local domain name.

2. Create a symbolic link to the newly created file in the /etc/nginx/sites-enabled directory and reload the Nginx service for updates to take place.

cd /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/server
sudo service nginx restart

Test your setup and Voila!

Final result


  • If you encounter any issues at this point, you may need to open port 4000

on your host due to system firewall.

sudo ufw allow 4000/tcp
sudo ufw reload

The Startup

Get smarter at building your thing. Join The Startup’s +785K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Okpallannuozo Nnaemeka A.

Written by

Cloud Evangelist | Tech is key.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +785K followers.

Okpallannuozo Nnaemeka A.

Written by

Cloud Evangelist | Tech is key.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +785K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store