DEV Community

Cover image for How to deploy React JS and Node.js apps on a single DigitalOcean droplet using Nginx
Zeeshan Haider Shaheen
Zeeshan Haider Shaheen

Posted on • Updated on

How to deploy React JS and Node.js apps on a single DigitalOcean droplet using Nginx

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

Step 1- Login to DigitalOcean 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should see the following output:

Available applications
  OpenSSH
Enter fullscreen mode Exit fullscreen mode

We have to allow SSH connections by typing:

sudo ufw allow OpenSSH
Enter fullscreen mode Exit fullscreen mode

and then we'll enable the Firewall:

sudo ufw enable
Enter fullscreen mode Exit fullscreen mode

Press y and ENTER.

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

sudo ufw status
Enter fullscreen mode Exit fullscreen mode

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

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

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

Alt Text

Now go to your domain provider in my case I am using GoDaddy.
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

Installing Nginx

On your terminal write the following command:

sudo apt-get install nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should see the following output:

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
Enter fullscreen mode Exit fullscreen mode

Now we will enable Nginx HTTP by typing:

sudo ufw allow 'Nginx HTTP'
Enter fullscreen mode Exit fullscreen mode

and we can see the changes by typing:

sudo ufw status
Enter fullscreen mode Exit fullscreen mode

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

Testing Web Server:

We can test our server by typing:

systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Alt Text

Nginx Configuration

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

sudo nano /etc/nginx/sites-available/default
Enter fullscreen mode Exit fullscreen mode

Find the server_name line and replace the underscore with your domain name:

. . .

server_name example.com www.example.com;

. . .
Enter fullscreen mode Exit fullscreen mode

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

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

and then reload server by typing:

sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Now allow access to HTTP Firewall by typing the following command:

sudo ufw allow 'Nginx Full'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Press ENTER

Now install Certbot by typing:

sudo apt install python-certbot-nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

cd /var/www/example.com/html
Enter fullscreen mode Exit fullscreen mode

and create index.html file by typing:

cat > index.html
Enter fullscreen mode Exit fullscreen mode

and open it by using the following command:

nano index.html
Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

and add a path to it:

root /var/www/example.com/html;
Enter fullscreen mode Exit fullscreen mode

check any syntax error by typing:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

and restart Nginx

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

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 fullscreen mode Exit fullscreen mode

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"

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

Clone your project from GitHub

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

git clone yourrepolink.git
Enter fullscreen mode Exit fullscreen mode

installing dependencies

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

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
Enter fullscreen mode Exit fullscreen mode

Write reboot and login to your server again by writing

ssh-copy-id bob@server_ip_address
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;
    }
Enter fullscreen mode Exit fullscreen mode

check any syntax error by typing:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

and restart the server by using the following command:

sudo service nginx restart
Enter fullscreen mode Exit fullscreen mode

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

Thank you!

Discussion (4)

Collapse
hkrogstie profile image
Håvard Krogstie

Very cool, I did something similar with Apache, wish I had this guide, would have used Nginx instead. I wanted Continuous Deployment so I set up a GitLab webhook to trigger an additional python server on the same digital ocean droplet, which would then download the site and server as build artifacts, and start the server. The server got its own user and home directory as a security measure, but I'm not sure how much added security that actually provides.

One tip: I don't know how pm2 works, but I ended up running the python server on startup in a detached tmux session, which in turn starts the backend. This means i can check in on it using

sudo tmux attach -t manager
Enter fullscreen mode Exit fullscreen mode

Which was very nice when debugging webhooks

Collapse
zeeshanhshaheen profile image
Zeeshan Haider Shaheen Author

Yes, Nginx is very efficient and easy as compared to Apache. When I was learning Apache I found some problems in understanding particular things.
But Nginx is more easy than that.

As far as PM2, I just want to make sure that my apps is running after even if I logged out. So PM2 helps me out in this regard.

I was learning about Python server. It was quite interesting. Thanks for mentioning that..

Collapse
gabrieldissotti profile image
Gabriel Dissotti

Thanks!

The lib python-certbot-nginx was upgraded to python3-certbot-nginx

Collapse
zeeshanhshaheen profile image
Zeeshan Haider Shaheen Author

Thanks for mentioning that, I'll update that.
But 'python-certbot-nginx' was working fine with me.
But yes, I'll update that.
Thank you!!