How to deploy React JS and Node.js apps on a single DigitalOcean droplet using Nginx
Tags: node, react, devops, webdev
Published: 2020-11-24 16:49:00

In this article, we'll learn how to deploy a React JS app using a simple server block and a Node.js app using reverse proxy server blocks, on a single DigitalOcean droplet using Nginx. 

## Deploy a React app on DigitalOcean using Simple Server Block

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ppgi73o2sibewh4i1pqo.jpg)



## Step 1- Login to [DigitalOcean](https://www.digitalocean.com/)  and create a new droplet

### Access server using root 

Open your terminal and copy your ip_address of your droplet and write the commend below:

```
ssh root@server_ip_address
```
Now, enter your password, and you are logged into the server.

It's time to set up the Firewall.

## Basic Firewall Set up

For security reasons, we have to add a basic firewall.
Ubuntu servers use `UFW` firewall. It is a very easy process to set up a basic Firewall. 

We can see which applications our Firewall currently allows by using the following command:

```
sudo ufw app list
```
You should see the following output:

```
Available applications
  OpenSSH
```

We have to allow SSH connections by typing:

```
sudo ufw allow OpenSSH
```

and then we'll enable the Firewall:

```
sudo ufw enable
```
Press `y` and `ENTER`.

We can see our Firewall status by using the following command:

```
sudo ufw status
```

Now in the next step, we'll configure the domain name.

## Step 2 - Configure Domain Name

In this section, we'll configure the domain name that will be used for our React application. 

For this purpose, we have to purchase a domain(please visit [GoDaddy](https://godaddy.com) or any other domain provider) and link your domain to the DigitalOcean.

We will be doing this step by step.

In DigitalOcean, in the "Add a Domain" section, write your domain like: `sample.com`. It should not `www.sample.com` and click the add domain button.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/afrzzzmiw40w8f2vru98.png)

After that, you have to add NS records for your domain.

We'll be adding two `A` records, which maps an `IP4 address` to the domain name. 

For the first `A` record, enter `@` in `HOSTNAME` and server(ie: droplet) you want to point to your domain,

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g8xz2c519y79k0vgyfsf.png)

For the second `A` record write `www` in `HOSTNAME` and select the same server

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lttjlcq8s8e2sungqthp.png)


Now go to your domain provider in my case I am using [GoDaddy](https://godaddy.com).
Go to your profile and in the `Domain` section click `DNS`. 

In the `Nameservers` section click "change" and enter the following nameservers:

- `ns1.digitalocean.com`
- `ns2.digitalocean.com`
- `ns3.digitalocean.com`

It may take some time to change nameservers.

## Step 3 - Install Nginx 

Now your domain is pointing to the server it's time to install and configure Nginx.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2c8e5fikxpqoie477z7j.jpg)


### Installing Nginx

On your terminal write the following command:

``` 
sudo apt-get install nginx
```

It will install Nginx along with other dependencies.

### Configure Firewall

Before we can test Nginx, we need to reconfigure our firewall software to allow access to the service.

We can list the applications configurations that `ufw` knows how to work with by typing:

```
sudo ufw app list
```

You should see the following output:

```
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
```

Now we will enable `Nginx HTTP` by typing:

```
sudo ufw allow 'Nginx HTTP'
```
and we can see the changes by typing:

```
sudo ufw status
```

Now we'll test Ngnix if it's working fine.

### Testing Web Server:

We can test our server by typing:

```
systemctl status nginx
```

output should looks like this:

```
● nginx.service - A high performance web server and a reverse proxy server
    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
    Active: active (running) since Mon 2016-04-18 16:14:00 EDT; 4min 2s ago
  Main PID: 12857 (nginx)
    CGroup: /system.slice/nginx.service
      ├─12857 nginx: master process /usr/sbin/nginx -g daemon on; master_process on
      └─12858 nginx: worker process
```

Now enter your ip_address into the browser and you should see the Nginx landing page.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dx5c9s84ukgg1uicd9aq.png)


### Nginx Configuration

Open the default config file with nano or your favorite text editor:

```
sudo nano /etc/nginx/sites-available/default
```
Find the server_name line and replace the underscore with your domain name:

```
. . .

server_name example.com www.example.com;

. . .
```
Save the file and exit the editor and verify any error by typing:

```
sudo nginx -t
```
and then reload server by typing:

```
sudo systemctl reload nginx
```
Now allow access to HTTP Firewall by typing the following command:

```
sudo ufw allow 'Nginx Full'
```

## Step 4 - SSL Configuration Using Let's Encrypt and Certbot

Let's Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx.

### Install Certbot

First we will add the repo. to the server:

```
sudo add-apt-repository ppa:certbot/certbot
```
Press `ENTER` 

Now install Certbot by typing:

```
sudo apt install python-certbot-nginx
```

### Get SSL Certificates From Certbot


To get SSL certificates for your example.com and www.example.com URLs, use this command 

```
sudo certbot --nginx -d example.com -d www.example.com
```

After that, Certbot will ask how you'd like to configure your HTTPS settings.

```
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cance
```
Select `ENTER`. Now your website server on `HTTPS`.

Now enter your domain and test it.

## Step 5 - Deploying React APP

First of all, create a folder on your website name, in my case, it's `example.com` in `/var/www/`.

```
sudo mkdir -p /var/www/example.com/html
```

Now go to `/var/www/example.com/html` by using 

```
cd /var/www/example.com/html
```
and create `index.html` file by typing:

```
cat > index.html
```
and open it by using the following command:

```
nano index.html
```
Inside the file, create a basic HTML file.

```

<html>
  <head>
    <title>Hello World!!!</title>
  </head>
  <body>
    <h1>Success! The example.com server block is working!</h1>
  </body>
</html>

```

Save and close the file.

### Re-configuring Nginx

Now that you have the content created in the new `/var/www/example.com/html` directory, you need to tell Nginx to serve that directory instead of the default `/var/www/html` it currently is.

By using the following command add root to the file and tell Nginx the path

open the file by using:

```
sudo nano /etc/nginx/sites-available/default
```

and add a path to it:

```
root /var/www/example.com/html;
```

check any syntax error by typing:

```
sudo nginx -t
```
and restart Nginx

```
sudo systemctl restart nginx
```

Now enter your domain name and test your site.

### Deploying React App

Now open your app in the terminal  and run the following command into your App's terminal:

```
scp -r ./build/* user@server_ip_address:/var/www/example.com/html
```
Enter the password and you are good to go.

Now open `package.json` file in your `React App` and in "scrips" section add the following code:

```
 "deploy-production": "react-scripts build && scp -r ./build/* user@server_ip_address:/var/www/example.com/html"

```

Write your ip_address and your website name instead of `server_ip_address` and `example.com`.

Now run the following command:

```
npm run deploy-production
```

Now write your domain name into the browser. If you didn't make any mistakes, your React website is deployed.

# Deploy NodeJS app on DigitalOcean using reverse proxy server blocks


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u4eeesqm3xpxbpjh22fo.jpg)


We have our firewall `"ufw"` configured and `Nginx` is installed and configured, our 70% of work is done already. It will not take much time.

## Installing Node

write the following commands on the terminal:

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

sudo apt install node.js

node --version

```

## Clone your project from GitHub

copy the link from your GitHub repo. and run the following command


```
git clone yourrepolink.git
```

## installing dependencies

```
cd yourproject
npm install
npm start (or whatever your start command)
# stop app
ctrl+C
```
## Installing PM2 to keep your app running

```
sudo npm i pm2 -g
pm2 start app.js (app.js is the file name)

# To make sure app starts when reboot
pm2 startup ubuntu
```

Write `reboot` and login to your server again by writing

```
ssh-copy-id bob@server_ip_address
```

Now in `/etc/nginx/sites-available/default` add another server block and add `server_name` and write your subdomain. In my case, it would be 
`nodejs.example.com`.

```
    server_name nodejs.example.com
```

under the `server_name` add the following location part:


```

    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 any syntax error by typing:

```
sudo nginx -t
```

and restart the server by using the following command:

```
sudo service nginx restart
```

Now in `DigitalOcean` in the "Add a Domain" section, open `CNAME` and any subdomain name in my case it is `node.js` so you can see `nodejs.example.com` under HOSTNAME and select the same droplet.
 

#### Now a React App and Node.js apps are hosted on a single DigitalOcean droplet.

I hope this article was very helpful. If you have any questions, let me know in the comment section.

I am a beginner so any suggestions from the seniors will be appreciated.

PS: I am currently on my #100DaysOfCode challenge. To see my daily progress, follow me on Twitter [@zeeshanhshaheen](https://twitter.com/zeeshanhshaheen)

Thank you!