Deploying and Securing Your Node.js App on a DigitalOcean Droplet: A Comprehensive Step-by-Step Deployment Guide with SSL.
Tags: node, deployment, ssl, devops
Published: 2023-10-13 09:19:05

## Introduction
Nodejs is one of the most popularly used web development runtime environments, it is the backbone of all javascript frameworks including popular ones like, react, angular, express, and so on. Nodejs can be used to develop various kinds of applications including frontend and backend. Our major concern in this article is to deploy a very simple nodejs backend application and add security to it. Follow along...

## Prerequisites
1. Your local development environment for nodejs development.
2. A digitalocean account (you can use any other provider of your choice)
3. A domain name, I have a domain name on a cpanel managed hosting plan, but you can use any domain name provider of your choice.

## Table of content
1. Create a basic nodejs app and run it locally.
2. Provision a droplet on digitalocean.
3. Access droplet and update packages.
4. Install node on droplet.
5. Install nginx on the droplet.
6. Pull the application and run it.
7. Setup DNS Record.
8. Setup reverse proxy
9. Secure the application using SSL.

## Create a basic nodejs app and run it locally
For this step I have already created a very simple nodejs application, all you have to do is to clone the repo and follow these steps to run it locally.

1. Clone the repo https://github.com/talibackend/very-slim-nodejs-app.git
2. Enter the directory where the repo was cloned.
3. Run `npm install` to install the npm packages.
4. Create a new file `.env` copy the content of `.env.example` into it, you can change the port if you want to.
5. Run npm start, you should get a message in the console saying the droplet is running on the port you entered in the `.env` file.
6. To confirm that every worked fine try to access http://localhost:{PORT IN ENV} in your browser, some JSON value should be printed on your browser.
![JSON Response from our application](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gp8kyukwytfx94kpihn.png)
```
NOTE: Before running the application, please make sure nothing is running on the port you provided.
```

## Provision a droplet on digitalocean
1. Log in to your digitalocean account and create a new project.
2. Inside the project, click on the create dropdown and select droplet.
3. Select all the options that match your choice.
4. Select `ubuntu` as the OS and pick version `20.04`.
5. In the authentication section, select `Password` and enter the password you wish to use to log into your droplet. Copy and save the entered password in a secure place.
6. Click **Create droplet**, the process can take up to 2 minutes before the droplet will be up.

## Access droplet and update packages
After provisioning our droplet, we need to access it and update the system software, to do this we can simply follow the steps below:

1. Copy the ip4 address of your droplet from your digitalocean dashboard.
2. Open Terminal(For Mac and Linux users. Windows users can use a ssh client like putty).
3. Enter `ssh root@ip-address`, `ip-address` should be the ip address of the droplet.
4. The terminal will ask for the password, please enter the password you provided while provisioning the droplet.
5. Once inside the droplet run `sudo apt update && sudo apt upgrade`.

## Install node on droplet
There are various ways of installing nodejs on a Linux distribution, in this article we will use node version manager(nvm), this tool allows us to install any version of node on our machine easily, let's install node by following these steps:

1. Run `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash`
2. Then run `source ~/.bashrc`
3. By now nvm should have been installed on your droplet, run `nvm install v18.1.0` to install version 18.1.0 of nodejs.
4. Run `node -v` to confirm that node has been installed on our droplet.
5. Since we already have node installed on our droplet, `npm` has been installed alongside, we need to use npm to install a process manager called `pm2` this is what we will use to run our nodejs application as a service. We will install it by running `npm install -g pm2`.

## Install nginx on droplet
In this section we will install nginx on our droplet, nginx is a simple lightweight web server that can be used for various activities including reverse proxy which we are most interested in. We will install nginx on our droplet by following these steps:

1. Run `sudo apt install nginx`, this should install nginx and start running it on our droplet.
2. To confirm that nginx is running visit `http://droplet-ip`, the default nginx page should be displayed on your browser.

## Pull the application and run it
Now that we have installed all the requirements to run our application, we can then pull the application's source onto the server and run it. We will take the following steps to achieve this:

1. Inside your droplet run `git clone https://github.com/talibackend/very-slim-nodejs-app.git`
2. Run `cd very-slim-nodejs-app`
3. Run `cp .env.example .env`, this will copy the content of the first file into the second, therefore we will have a `.env` file that contains the same content as our `.env.example` file. In most cases, we will have to edit the .env file, but it does not contain sensitive data in our case so we will leave it like that.
4. We will then run `npm install` this will install all the node modules that our application needs to run.
5. We can now start our application by running `pm2 start --name slim-app "npm start"`.
6. We will run `pm2 logs` to confirm that our application is running properly.
7. To further verify the status of our application we will try to access `http://droplet-ip:5066` in the browser, we should get the JSON response from our application.

## Setup DNS Record
For this step we want to set up a new domain name for our nodejs application, this step is quite different for various providers, in our case, I will be using a domain managed by cpanel. Please follow along.

1. Login to your cpanel.
2. Navigate to zone editor.

![Click ZONE EDITOR](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mj0v49lu0nsm9dfhyb7p.png)

Click on **+ A Record**.

![Click + A Record](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldj6vyjti64btehjd8k4.png)

Enter the domain name and IP address, in my case, my domain name is `very-slim.schovela.com.ng`, and the IP address is the IP address of our droplet.

![Fill zone details](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t1ruxiklqh4vyh6e77jv.png)

Click on **Add Record** and wait a few minutes.

To confirm that the propagation succeeded, access `http://your-domain` and the `http://your-domain:5066`, they should return the nginx default page and JSON response from our application respectively.

## Setup reverse proxy
At this point, we have both nginx and our nodejs application running on our droplet and also ready to receive traffic, but this is not our goal, the purpose of this step is to send every request on `http://your-domain` to our nodejs application that is running internally at `http://localhost:5066`. We can achieve this using one of the most important features of nginx called `reverse proxy`. Please follow along:

1. Inside our droplet we will run `cd /etc/nginx/sites-enabled` this is to change the directory to the nginx configuration directory.
2. Then we will run `cp default old-default.txt`, this is to copy the default configuration content into the `old-default.txt` file for backup reasons.
3. Run remove `rm default`, this is to delete the default file.
4. Then run
```
    echo "server {
            listen 80;
            server_name your-domain;

            location / {
                proxy_pass http://localhost:5066;
            }
        }" > default
```
The code above will create the default file and add the configuration content to it.

5. You can then run `sudo systemctl restart nginx`, this will restart our nginx service with the new configuration.
6. In order to confirm that our reverse proxy works, accessing `http://your-domain` should return the JSON from our application.

## Secure the application with SSL
At this point we are pretty much done with everything we want to do, the only thing is that our site uses `http` which is not secure, we need our site to be available on `https`. HTTPS is the secured version of HTTP, it uses `SSL` to encrypt data flowing into and out of our application, to install SSL on our app we will use an open-source tool called `certbot`. Certbot allows you to install SSL on various types of applications within your machine. Please follow the steps below.

1. First we need to install certbot by running `sudo apt install certbot python3-certbot-nginx`.
2. Then we will install SSL by running `sudo certbot --nginx -d your-domain`.
3. You will be asked to provide your email.
4. Then you will also be asked to allow automatic redirect from http to https, please enter 2, to allow redirect.
5. Then we run `sudo systemctl restart nginx`.
6. To confirm that our SSL installation was successful, please try to access `https://your-domain` in the browser, it should return the JSON response from our application.

If you prefer to watch me demonstrate all the steps, please check out my video {% embed https://youtu.be/o1Chphknx0s %}

### Thank for Reading.....