Deploy Multiple NodeJS Apps on single Server with SSL, Nginx, PM2 - Part 1
Tags: javascript, node, tutorial, devops
Published: 2022-08-21 12:04:00

## 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

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

# and then 

sudo bash nodesource_setup.sh
```
after this the PPA is added we can Simple install the Node js
```sh
sudo apt install nodejs
```
for checking the version of Node we installed simply type 
```
 node -v
```
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 
```sh
sudo apt install build-essential
``` 
## Step 02  - Clone the project & Install Dependencies 
```sh
git clone awesomeproject.git

cd awesomeproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C
```
or you can create simple app 
```
cd ~
nano app.js
```
insert the following into the file

```javascript
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}/`);
});
```
and then run it

```
node app
```
you will receive following as output 
```sh
Output
Server running at http://localhost:3000/
```

## Step 03 - Setup PM2 
firstly we need to install the PM2
```sh
sudo npm i pm2 -g
```
and for starting the app
```sh
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
```
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) 
```sh
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)
```

## Step 05 - Install NGINX and Configure
installing Nginx is pretty easy just type following 
```sh
sudo apt install nginx
``` 
and open default config to edit
```sh
sudo nano /etc/nginx/sites-available/default
```  
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;
    }
```
then check and restart the NGINX 

```
# Check NGINX config
sudo nginx -t

# Restart NGINX
sudo service nginx restart
```
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  
```sh
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python3-certbot-nginx
```
and then add certificates for the domains we have added

```sh
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
```
and your app should be live on https://yourdomain.com.

please note we have to renew these certificates every 90 days 
to renew run 
```sh
certbot renew 
```
we will add another app in next part stay tunned for that  😃