Unlike Heroku, where the stage is set for you and you just have to push your local Git Repository, Digital Ocean is an infrastructure as a service. In other words, Digital Ocean requires you to manually configure and maintain virtualized servers . However, this comes with a lot of flexibility and freedom. DigitalOcean is known for its high-performance servers. All their cloud servers are SSD based and promise a start-up time of only 55 seconds!

Today we will look at how we can deploy a NodeJS and ExpressJS Application on a Digital Ocean Droplet with NGINX as a reverse proxy. We will also setup a Free Let’s Encrypt SSL Certificate on our application. This sure sounds overwhelming, but we will go through each and every step in detail. Let’s get to work!

Overview of our NodeJS and ExpressJS Application

In this article, we will be deploying a simple NodeJS and ExpressJS application which only has one route that responds to a GET request with a simple HTML file. You can clone the Github Repository containing the project files here. Or feel free to use any of your own projects to follow along this step by step guide. This is what our server.js file looks like,

const express = require("express"); const app = express(); const path = require("path"); app.get("/", (req, res) => { return res.sendFile(path.join(__dirname + "/index.html")); }); const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(`Server Running on Port ${PORT}`));

Setup your Digital Ocean Droplet

Register on Digital Ocean

If do not have an account on Digital Ocean, you can register using this link to get free $50 credit.

Droplet Setup

Step 1 — Go to your Digital Ocean Dashboard and choose Droplets.

Step 2 — Choose an Image and a plan.

For the sake of this article, we will choose Ubuntu 18.04.3 (LTS) x64 as our Distribution and a Standard plan for $5/mo.

Step 3 — Choose a datacenter region.

Step 4 — Choose Authentication Method and Generate SSH Key

We will use SSH Keys to Authenticate and connect to our Droplet. If you don’t have an SSH key configured, choose the New SSH Key option.

You can generate your SSH Keys using the following commands on your terminal,

ssh-keygen

You will then be prompted to save and name the key as follows,

Generating public/private rsa key pair. Enter file in which to save the key (/Users/USER/.ssh/id_rsa):

Hit the Enter or Return key.

Next you will be asked to create and confirm a passphrase for the key as follows,

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

This will generate two files, by default called id_rsa and id_rsa.pub .

To get the contents of your .pub file run the following command in your terminal,

cat ~/.ssh/id_rsa.pub

Copy and Paste the contents (SSH Key) of your .pub file in the SSH Setup of your droplet , name your public SSH Key and choose Add SSH Key.

Step 5 — Choose a hostname for your Droplet

In our case, we will name it as node-deploy-tutorial. Feel free to choose any name.

We will let the rest of the configurations stay as default. Now scroll down and choose Create Droplet.

Your server is now up and running on the web!

Connect to your Droplet

As mentioned earlier, we will connect to our Droplet using SSH Keys. For the sake of this article, we use the root user to connect. (However, you are recommended to create a new user.)

Copy the public IP of your droplet in the Resources section of your project.

Now run the following command in your terminal to connect to your Droplet,

ssh root@yourpublicipaddress

You have now successfully SSH ed into your Ubuntu Server/Droplet!

Set up your Server

Setup NodeJS

Run the following commands in your server’s terminal to setup NodeJS,

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



sudo apt install nodejs



node --version

Setup your Project

Run the following commands in your server’s terminal,

sudo mkdir app cd app sudo git clone https://github.com/abdamin/NodeJS_Deploy_To_DigitalOcean_Tutorial.git

Note that this is the Github Repository URL of our sample NodeJS and ExpressJS App. If you are deploying your own application, you will use your own Repository URL when you use the clone command.

Now we will install our project dependencies using the following commands,

cd {{your cloned repository’s name}} npm install

Setup PM2

Note that we will not use the npm start command to run our application. Instead, we use PM2 that will allow our application to run in the background.

Run the following in your server’s terminal to install PM2 globally,

npm install pm2 -g

To run your application with PM2, run the following command while in your project directory,

pm2 start server.js

Note that server.js is the name of our application’s endpoint. If your project has a different endpoint, make sure you replace server.js in the above command with the name of your endpoint.

To make sure that PM2 restarts when our Droplet reboots, run the following command in your server’s terminal,

pm2 startup ubuntu

Firewall Setup

Run the following to enable the firewall,

sudo ufw enable

However, you will need to configure the firewall to allow HTTP, HTTPS and SSH access. Run the following commands in your server’s terminal,

sudo ufw allow http sudo ufw allow https sudo ufw allow ssh

Setup NGINX

Now we need to install NGINX to configure a reverse proxy for our application.

Run the following in your server’s terminal,

sudo apt install nginx

Link your project with NGINX

Run the following command in your server’s terminal to open the default file using Vim,

sudo vim /etc/nginx/sites-available/default

If you have not used Vim before, check this guide on basic vim commands.

Inside the location block, which is nested inside the server block, remove the following line of code,

try_files $uri $uri/ = 404;

Also, add the following lines of code inside the location block (Editing the placeholder text with your App Port Number off-course),



proxy_pass

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;

proxy_pass http://localhost: {{YOUR-APP-PORT-IN-YOUR-CODE}} ; 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;

Also, if you want to successfully configure an SSL Certificate for your application (which we will in a moment) and add a custom domain, don’t forget to add the following line of code inside the server block and before the location block. We will use the custom domain abdullahsumsum.com for the sake of this article.

server_name abdullahsumsum.com www.abdullahsumsum.com;

Make sure you save the file by pressing the esc key, then typing :wq and then pressing the return key to save and close the vim editor.

The following is what our server block in our default file should look like after making the above changes,

Run NGINX

Run the following commands in your server’s terminal,

sudo nginx -t sudo service nginx restart

You should now be able to visit your application by typing your public IP on the browser!

Custom Domain Setup

Add a custom domain to your Droplet

Step 1 — Go to the Networking section.

Step 2 — Enter Domain Name

Step 3 — Add A Records for your custom domain

Add two A records with hostnames @ and www

Domain Registar Configuration

I personally prefer using NameCheap as my domain registrar. If you are using Namecheap, you can use this link to access their latest promotional offers. However, you can use any registrar to follow along this guide. Basically, all you have to do is configure your domain to point to the Digital Ocean Name Servers.

You need to add the 3 following name servers in your DNS Manager,

ns1.digitalocean.com

ns2.digitalocean.com

ns3.digitalocean.com

Note that changes might take up to 48 Hours to propogate. However, this usually takes up to 5–10 minutes.

You should now be able to access your application using your custom domain name!

SSL Certificate Setup

We will use Cerbot to set up a Free Let’s Encrypt SSL Certificate for our application. We will also configure it make sure it renews automatically after its 90 day expiry period.

Setup Cerbot

Run the following commands in your server’s terminal to setup cerbot,

sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install python-certbot-nginx

Issue Certificate for your custom domain

Run the following command with your custom domain name in your server’s terminal,

sudo certbot --nginx -d customdomain.com -d www.customdomain.com

You will then be prompted to choose whether you want to redirect all requests to secure HTTPS. Type 2 in your terminal to redirect all requests to HTTPS. Otherwise type 1.

Setup Auto Renewal

Since our certificate expires every 90 days, we will have to generate a script that renews our certificate automatically. Run the following command in your server’s terminal,

certbot renew --dry-run

Conclusion

Your NodeJS Project has now been successfully deployed! You should be able to access your Web Application through a secure SSL connection!

If you have any questions, feel free to leave a comment. Also, if this helped you, please like and share it with others. I publish articles related to web development regularly. Consider entering your email here to stay up to date with articles and tutorials related to web development. You can also find out more about what I do at abdullahsumsum.com