Skip to content

Instantly share code, notes, and snippets.

@navsqi
Forked from bradtraversy/node_nginx_ssl.md
Last active December 1, 2021 13:16
Show Gist options
  • Save navsqi/22f29538ba13aa7abc1999247e47036b to your computer and use it in GitHub Desktop.
Save navsqi/22f29538ba13aa7abc1999247e47036b to your computer and use it in GitHub Desktop.
Node app deploy with nginx & SSL

Node.js Deployment

Steps to deploy a Node.js app to Ubuntu Server using PM2, NGINX as a reverse proxy and an SSL from LetsEncrypt

1. Create a new user

# creating new user
adduser lukas

# providing superuser rights
usermod -aG sudo lukas

1. Install Node/NPM

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -

sudo apt install nodejs

node --version

OR

# this command will download install script with curl
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

# or use wget
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

Now log out and log back in. After this, you should be able to use nvm commands.

# check if installed
nvm --version

# list available Node.js versions
nvm ls-remote

# choose one version and install it
# example of v10.4.1 installation
nvm install v10.4.1

# check if installed properly
node --version

# check more nvm usage
nvm --help

2. Install Git

sudo apt update
sudo apt install git

# check if git has installed
git --version

read more on blog https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-18-04-quickstart

3. Clone your project from Github

There are a few ways to get your files on to the server, I would suggest using Git

git clone yourproject.git

4. Install dependencies and test app

cd yourproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C

5. Setup PM2 process manager to keep your app running

sudo npm i pm2 -g
pm2 start app (or whatever your file name)

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

# To make sure app starts when reboot
pm2 startup ubuntu

You should now be able to access your app using your IP and port. 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)

6. Replace Apache with NGINX on Ubuntu 18.04

sudo systemctl stop apache2
sudo systemctl disable apache2
sudo apt remove apache2
sudo apt autoremove

if error apache2 service is masked, It appears that you had an empty service file or you have a duplicate service file in /etc/systemd/system/. This will usually get masked. Check if the file /etc/systemd/system/apache2.service exists. If so, remove it.

sudo apt clean all && sudo apt update && sudo apt dist-upgrade
sudo apt install nginx

read more on blog https://lowendbox.com/blog/how-to-replace-apache-with-nginx-on-ubuntu-18-04/

OR you can change port apache to 8080

sudo nano /etc/apache2/ports.conf
sudo nano /etc/apache2/sites-available/000-default.conf

you can remove apache default welcome page

rm /var/www/html/index.html

7. Setup ufw firewall

# if ufw not installed
sudo apt-get install ufw

sudo ufw enable
sudo ufw status
sudo ufw allow ssh (Port 22)
sudo ufw allow http (Port 80)
sudo ufw allow https (Port 443)
sudo ufw allow 8045 (ufw will allow port 8045)

8. Install NGINX and configure

sudo apt install nginx

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:5000; #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;
    }
# Check NGINX config
sudo nginx -t

# Restart NGINX
sudo service nginx restart

Readmore: https://www.digitalocean.com/community/questions/setting-up-multiple-nodejs-applications-using-nginx-vitual-hosts

You should now be able to visit your IP with no port (port 80) and see your app. Now let's add a domain

9. Add domain in Digital Ocean

In Digital Ocean, go to networking and add a domain

Add an A record for @ and for www to your droplet

Example targeting A record

+------+------+-------+----------------+
| Name | Type | TTL   | RDATA          |
+------+------+-------+----------------+
| @    | A    | 14400 | 45.130.229.222 |
+------+------+-------+----------------+
| www  | A    | 14400 | 45.130.229.222 |
+------+------+-------+----------------+
| api  | A    | 14400 | 45.130.229.222 |
+------+------+-------+----------------+

NAME = subdomain
example: name = api , it means we targeting api.domain.com to vps

RDATA / IP VPS

Register and/or setup domain from registrar

I prefer Namecheap for domains. Please use this affiliate link if you are going to use them https://namecheap.pxf.io/c/1299552/386170/5618

Choose "Custom nameservers" and add these 3

  • ns1.digitalocean.com
  • ns2.digitalocean.com
  • ns3.digitalocean.com

It may take a bit to propogate

10. Add SSL with LetsEncrypt

On Ubuntu 20.04

snap install certbot --classic
certbot --version
sudo certbot --nginx --test-cert
sudo certbot --nginx
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Only valid for 90 days, test the renewal process with
certbot renew --dry-run

Now visit https://yourdomain.com and you should see your Node app

Improving Nodejs performance with clustering

https://blog.appsignal.com/2021/02/03/improving-node-application-performance-with-clustering.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment