DEV Community

Cover image for Deploy Multiple NodeJS Apps on single Server with SSL, Nginx, PM2 - Part 1
Ranjan Singh
Ranjan Singh

Posted on

Deploy Multiple NodeJS Apps on single Server with SSL, Nginx, PM2 - Part 1

Motivation

Greatings, Let's say you finished coding your awesome NodeJS app ready to deploy to server and wanted to host it on a VPS or you have more than one app to host to single VPS how would you do that.

Introduction

Nginx: Webserver or reverse proxy to handle incoming requests.
PM2 : Process Manager to manage your NodeJS Apps Like making sure it's running all the time even it catches an error or making sure to create multiple instance of the same app to utilise app available cores/threads (Cluster Mode) last part is optional.
Certbot : Managing App SSL for your domains using Let's Encrypt SSL for Free.

Prerequisites

An Ubuntu 20.04 server with SSH access and a non-root user with sudo privileges.

Step 01 - Installing Node.js

Firstly to install the node js we need to add the PPA for the most recent LTS Version

cd ~
curl -sL https://deb.nodesource.com/setup_16.x -o nodesource_setup.sh

# and then 

sudo bash nodesource_setup.sh
Enter fullscreen mode Exit fullscreen mode

after this the PPA is added we can Simple install the Node js

sudo apt install nodejs
Enter fullscreen mode Exit fullscreen mode

for checking the version of Node we installed simply type

 node -v
Enter fullscreen mode Exit fullscreen mode

and it will show you exact version of the installation in my case it's 16.17.0.

Most likely we gona need build-essentials for compiling any package from source code so let's install that as well

sudo apt install build-essential
Enter fullscreen mode Exit fullscreen mode

Step 02 - Clone the project & Install Dependencies

git clone awesomeproject.git

cd awesomeproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C
Enter fullscreen mode Exit fullscreen mode

or you can create simple app

cd ~
nano app.js
Enter fullscreen mode Exit fullscreen mode

insert the following into the file

const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello Everyone!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
Enter fullscreen mode Exit fullscreen mode

and then run it

node app
Enter fullscreen mode Exit fullscreen mode

you will receive following as output

Output
Server running at http://localhost:3000/
Enter fullscreen mode Exit fullscreen mode

Step 03 - Setup PM2

firstly we need to install the PM2

sudo npm i pm2 -g
Enter fullscreen mode Exit fullscreen mode

and for starting the app

pm2 start app  #(or whatever your file name)

#for Cluster mode 
pm2 start app -i max 
#it will create an instance for every available thread 
#optionally you can also pass Number like 2,3 for instances count

# Other pm2 commands
pm2 show app
pm2 status
pm2 restart app
pm2 stop app
pm2 logs (Show log stream)
pm2 flush (Clear logs)

# To make sure app starts when reboot
pm2 startup ubuntu
Enter fullscreen mode Exit fullscreen mode

the app should be accessible using the IP and port defined.

Step 04 - Setup UFW Firewall

Now we want to setup a firewall blocking that port and setup NGINX as a reverse proxy so we can access it directly using port 80 (http) or port 443 (https)

sudo ufw enable
sudo ufw status
sudo ufw allow ssh (Port 22) # for SSH
sudo ufw allow http (Port 80)
sudo ufw allow https (Port 443)
Enter fullscreen mode Exit fullscreen mode

Step 05 - Install NGINX and Configure

installing Nginx is pretty easy just type following

sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

and open default config to edit

sudo nano /etc/nginx/sites-available/default
Enter fullscreen mode Exit fullscreen mode

Add the following to the location part of the server block

    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000; #whatever port your app runs on
        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;
    }
Enter fullscreen mode Exit fullscreen mode

then check and restart the NGINX

# Check NGINX config
sudo nginx -t

# Restart NGINX
sudo service nginx restart
Enter fullscreen mode Exit fullscreen mode

You should now be able to visit your IP with no port (port 80) and see your app.

Step 06 - Adding Domain

Adding a domain to Any VPS is very different on each provider first you need to register and add a A record to point that to the IP address of the VPS or If your VPS Provider Supports you can also add Custom Nameservers it may take a while to show up.

Step 07 - Add SSL with Lets Encrypt

Lets Encrypt provides free SSL with certbot package so first we need to install the package

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python3-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

and then add certificates for the domains we have added

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Enter fullscreen mode Exit fullscreen mode

and your app should be live on https://yourdomain.com.

please note we have to renew these certificates every 90 days
to renew run

certbot renew 
Enter fullscreen mode Exit fullscreen mode

we will add another app in next part stay tunned for that 😃

Top comments (2)

Collapse
 
estotriramdani profile image
Esto Triramdani N

Thanks for sharing!
This is what I am looking for lately🍻

Collapse
 
ranjan profile image
Ranjan Singh

I'm glad you found it useful 😁