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
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
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 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.
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,
For the second A
record write www
in HOSTNAME
and select the same server
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.
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.
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
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
Thank you!
Top comments (5)
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
Which was very nice when debugging webhooks
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..
Thanks!
The lib python-certbot-nginx was upgraded to python3-certbot-nginx
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!!
Should i create a new directory while cloning node.js ? Or in which directory should I clone my node js repo?