Let's get started!
Table of Contents
- Create & Configure a New Server
- Configure Domain Name
- Install & Configure Nginx
- SSL Configuration Using Let's Encrypt and Certbot
- Create and Deploy a Create-React-App Website
Step 1 - Create & Configure a New Server
Before we can do anything, we need to set up and configure a VPS (Virtual Private Server) in the cloud to host your website on. There are a lot of companies that provide this service, but we'll use DigitalOcean.
To start, you need to create an account on DigitalOcean or log in to your existing account.
For a FREE $100 CREDIT FOR 60 DAYS, use this link: https://m.do.co/c/ce20017d8588.
They will ask you for a credit card, but you can cancel anytime before the 60 days end and not be charged.
Create a New Droplet on DigitalOcean
After logging in or successfully signing up for a new account, open the "Create" drop-down menu and click the "Droplets" link.
This will take you to the "Create Droplets" page where you'll be given some configuration options before creating a new server.
In the first section, select the Ubuntu operating system for your server.
Then, choose the $5 per month standard plan, which will give your application plenty of computing power to start with. You can easily upgrade in the future if needed.
Next, they allow you to choose the datacenter region for your server. This is the physical location for your server and, therefore, you should choose the one closest to the people visiting your website.
In the "Authentication" section, make sure the "Password" option is selected and enter a strong root password for your server. This is the password we'll use to initially SSH into your server.
Also, you can choose a hostname for your server. This will give your server a name to remember it by.
When you're done selecting options, hit the "Create Droplet" button to kick off the creation of your new server.
When the Droplet is fully up and running, the control panel will display the server's IP address.
Your server is now up and running!
In the next step, we'll complete the initial configuration process for the server. This will include logging into the server, setting up SSH access to the server, and creating a basic firewall.
Access Server Using Root
The first step is to gain access to the server using your root login.
To do this, you'll need both the IP address of the server and the private key (password) for the root user's account you created in the last section.
To log into your server, open a terminal (
Ctrl+Alt+T for Linux) on your local machine. Once you have a terminal open, use the following command to SSH in as the root user (replace the
server_ip_address word with your server's public IP address):
Accept the warning about host authenticity, if it appears, and provide the root password you created.
root user in a Linux environment has very broad privileges and, for that reason, you are discouraged from using it egularly. This is because very destructive changes (even by accident) can be made while using it.
Therefore, in the next step, we are going to create an alternative account with limited scope that will be used for daily work.
Create a New User
Logged in as
root, we can create a new user account that will be used to log in from this point forward. You can create a new user with the following command (substitute
bob with your username):
You'll be asked some questions starting with the password. Choose a strong password and fill in any of the optional information after that. You can just hit
ENTER repeatedly to skip the rest of the questions after that.
Give Your New User Root Privileges
You now have a new user account with regular account privileges. But you might occasionally need to do administrative tasks that require root privileges. So, instead of logging out of your normal user and logging back in as the
root account, we can give the normal account the ability to run root privileged commands when you need to by adding
sudo before each command.
To do this, we need to add your new user to the
sudo group on the machine.
root, run the following command to add your user to the
sudo group (substitute
bob with your username):
usermod -aG sudo bob
Now your user can run commands with
The next server configuration steps will help increase the security of your server. They are optional but highly recommended.
Add Public Key Authentication
By setting up public-key authentication for the new user, it will increase your server's security by requiring a private SSH key to login in instead of anyone being able to access the server via password.
Let's get pubic key authentication configured.
Generate a Key Pair
If you don't already have an SSH key pair, which consists of a public and private key, you need to generate one. If you already have a key that you want to use, skip to the Copy the Public Key step.
To generate a new key pair, enter the following command at the terminal of your local machine:
You'll receive an output similar to the following:
Generating public/private rsa key pair. Enter file in which to save the key (/Users/yourusername/.ssh/id_rsa):
ENTER to accept the file name and path.
Next, you'll be prompted to enter a password to secure the newly created key. You can either create a password or leave it blank. This generates a private key,
id_rsa, and a public key,
id_rsa.pub, in the
.ssh directory of your home directory.
Copy the Public Key
Now that you have the SSH key pair on our local machine, you need to copy our public key to the server.
Use one of the two options below to do this.
Option 1: SSH-Copy-Id
If your local machine has the
ssh-copy-id script installed, you can use it to install your public key to any user that you have login credentials for. If not, use Option 2 to install the key manually.
Still on your local machine, type the following command (replace
server_ip_address with your username and server public IP address):
You'll be asked for the user's password.
After successfully authenticating, your public key will be added to the server user's
.ssh/authorized_keys file. The corresponding private key can now be used to log into the server.
You can skip the next section on installing the key manually and jump to the Disable Password Authentication section.
Option 2: Install the Key Manually
Assuming you generated an SSH key pair using the previous step, use the following command at the terminal of your local machine to print your public key (
This should print your public SSH key, which should look something like the following:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBGTO0tsVejssuaYR5R3Y/i73SppJAhme1dH7W2c47d4gOqB4izP0+fRLfvbz/tnXFz4iOP/H6eCV05hqUhF+KYRxt9Y8tVMrpDZR2l75o6+xSbUOMu6xN+uVF0T9XzKcxmzTmnV7Na5up3QM3DoSRYX/EP3utr2+zAqpJIfKPLdA74w7g56oYWI9blpnpzxkEd3edVJOivUkpZ4JoenWManvIaSdMTJXMy3MtlQhva+j9CgguyVbUkdzK9KKEuah+pFZvaugtebsU+bllPTB0nlXGIJk98Ie9ZtxuY3nCKneB+KjKiXrAvXUPCI9mWkYS/1rggpFmu3HbXBnWSUdf firstname.lastname@example.org
Select the public key, and copy it to your clipboard.
To enable the use of a SSH key to authenticate as the new remote user, you must add the public key to a special file in the user's home directory.
On the server, as the
root user, enter the following command to temporarily switch to the new user (substitute
bob with your username):
su - bob
Now you will be in your new user's home directory.
Create a new directory called
.ssh and restrict its permissions with the following commands:
mkdir ~/.ssh && chmod 700 ~/.ssh
Now open a file in
authorized_keys with a text editor. We will use nano to edit the file:
Now insert your public key (which should be in your clipboard) by pasting it into the editor.
CTRL-X to exit the file, then
Y to save the changes that you made, then
ENTER to confirm the file name.
Now restrict the permissions of the
authorized_keys file with this command:
chmod 600 ~/.ssh/authorized_keys
Type this command once to return to the
Now your public key is installed, and you can use SSH keys to log in as your user.
Disable Password Authentication
This step will only allow you to log into your server using the SSH key you just created. Only people who possess the private key that pairs with the public key that was installed will get into the server. This increases your server's security by disabling password-only authentication.
To disable password authentication, follow the proceeding steps.
root user or new
sudo user on your DigitalOcean server, open the SSH daemon configuration file using the following command:
sudo nano /etc/ssh/sshd_config
Find the line that says
PasswordAuthentication and change its value to
no. It should look like this after the change was made:
Save and close the file using the method:
To reload the SSH daemon and put the changes live, type the following command:
sudo systemctl reload sshd
Password authentication is now disabled. Now your server can only be accessed with SSH key authentication.
Test Log In Using SSH Key
Let's test logging in using the SSH key.
On your local machine, log in to your server using the new account that we created. Use the following command to do so (substitute your username and IP address):
Once authentication is provided to the server, you will be logged in as your new user.
Now your server is only accessible by someone who has the SSH keys you generated. Which, in this case, are only located on your local machine. This greatly improves the security of your server.
Basic Firewall Set Up
Another security improvement we can make to the server is to add a basic firewall.
Ubuntu servers can use the
UFW firewall to ensure only connections to certain services are allowed. It's a simple process to set up a basic firewall and will improve your server's security.
You can see which applications are
UFW currently allows by typing:
sudo ufw app list
This should output the following:
Available applications OpenSSH
We need to make sure the firewall allows SSH connections so that we can log back in next time. To allow these types of connections, type the following command:
sudo ufw allow OpenSSH
And then enable the firewall:
sudo ufw enable
y and then
ENTER to proceed.
You can see that SSH connections are still allowed by typing:
sudo ufw status
OpenSSH directive should be listed.
That was the last step in the initial set up for our server.
In the next section, we'll configure your domain name.
Step 2 - Configure Domain Name
In this section, we'll configure a domain name that you want to use for your React web application.
To set up a domain, we need to do two things:
- Purchase a domain name from a domain name registrar.
- Setup DNS (Domain Name System) records for your domain by using a DNS hosting service.
DigitalOcean is not a domain name registrar, which means you can't purchase a domain name from them. But, they do provide a DNS hosting service that makes it easy to configure a domain name with their servers.
Using DigitalOcean, let's configure DNS for your domain.
Back on the DigitalOcean website, open the "Create" drop-down menu and click the "Domains/DNS" link.
In the Add Domains section, enter your domain (this is usually the base only:
example.com and not
www.example.com) and click the Add Domain button.
Once you have hit the "Add Domain" button, you will be taken to the "Create new record" page. You now need to add NS records for the domain on DigitalOcean servers. You'll only be adding
A records, which maps an
IPv4 address to a domain name. This will determine where to direct any requests for your domain name.
Therefore, we need to create two
A records for your website.
For the first one, enter
@ in the
HOSTNAME field and select the server you want to point the domain name to:
For the second one, enter
www in the
HOSTNAME field and select the same server:
Make sure the
A records are pointed to the correct server droplet (same as the first two you created).
Awesome, we can move onto the next step.
Configure Your Domain Registrar To Direct Domains to DigitalOcean
To use the DigitalOcean DNS, you'll need to update the nameservers used by your domain registrar to DigitalOcean's nameservers instead.
As an example, we'll walk you through the steps for doing this for namecheap. But, these steps can be easily replicated for whatever other service you used (GoDaddy, HostGator, etc.).:
First, sign in to your namecheap account and click "Domain List" in the left-hand column. You will be presented with a dashboard listing all of your domains.
Click the "Manage" button of the domain you'd like to update.
In the "Nameservers" section of the resulting screen, select Custom DNS from the dropdown menu and enter the following nameservers:
Click the green checkmark to apply your changes. Now you are ready to move on to connecting the domain with your Droplet in the DigitalOcean control panel.
It may take some time for the name server changes to propagate after you've saved them.
During this time, the domain registrar communicates the changes you've made with your ISP (Internet Service Provider). In turn, your ISP caches the new nameservers to ensure quick site connections. This process usually takes about 30 minutes but could take up to a few hours depending on your registrar and your ISP's communication methods.
You should now have a domain pointing at your newly created DigitalOcean server.
Step 3 - Install & Configure Nginx
Now that your domain is pointing to your server, it's time to install nginx and set up our server to host web content.
We'll be using Nginx to host your website.
Nginx is one of the most popular web servers and helps host some of the largest and highest-traffic sites out there. It is more resource-friendly than Apache in most cases and can be used as a web server or a reverse proxy.
Let's get Nginx configured on your server.
Nginx is available in Ubuntu's default repositories, so installation is pretty straightforward.
On your DigitalOcean server, run the following commands to update your local
apt package index so we have access to the most recent package lists:
sudo apt-get update && sudo apt-get install nginx
apt-get command will install Nginx along with any other required dependencies.
When those commands finish, Nginx will be available for you to use on the server.
Adjust the Firewall
Before we can test Nginx, we need to reconfigure our firewall software to allow access to the service. Nginx registers itself as a service with
ufw, our firewall, upon installation. This makes it rather easy to allow Nginx access.
We can list the applications configurations that
ufw knows how to work with by typing:
sudo ufw app list
You should get a listing of the application profiles:
Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
There are three profiles available for Nginx:
- Nginx Full: Opens both port
80(normal, unencrypted web traffic) and port
- Nginx Http: Opens only port
80(normal, unencrypted web traffic)
- Nginx Https: Opens only port
443(TLS/SSL encrypted traffic)
It is recommended that you enable the most restrictive profile that will still allow the traffic you've configured. Since we haven't configured SSL for our server yet, in this guide, we will only need to allow traffic on port
You can enable this by typing:
sudo ufw allow 'Nginx HTTP'
And you can verify the change with this command:
sudo ufw status
You should see
Nginx HTTP listed in the output.
Test Your Web Server
The Nginx web server should already be up and running.
You can check with the systemd init system to make sure the service is running by typing:
systemctl status nginx
You should get an output that 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
You can access the default Nginx landing page to confirm that the software is running properly. You can access this through your server's domain name or IP address.
When you have your server's IP address or domain, enter it into your browser's address bar:
You should see the default Nginx landing page, which should look something like this:
You now have a web server running!
In the next step, we will configure
SSL certificates for your domain.
Step 4 - SSL Configuration Using Lets 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.
We'll use Certbot to obtain a free
SSL certificate for Nginx on Ubuntu 16.04 and set up your certificate to renew automatically.
The first step is to install the Certbot software on your server.
First, add the repository:
sudo add-apt-repository ppa:certbot/certbot
ENTER to accept.
Then update the package list to pick up the new Certbot repository information:
sudo apt-get update
Now install Certbot's Nginx package using the
apt package manager:
sudo apt install python-certbot-nginx
Certbot is now ready to use!
Update Nginx Configuration
Certbot can automatically configure
SSL for Nginx, but it needs to be able to find the correct server block in your config. It does this by looking for a
server_name directive that matches the domain you're requesting a certificate for.
Open the default config file with
nano or your favorite text editor:
sudo nano /etc/nginx/sites-available/default
Find the existing
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.
Then, verify the syntax of your configuration edits with:
sudo nginx -t
If you get any errors, reopen the file and check for typos, then test it again.
Once your configuration's syntax is correct, reload Nginx to load the new configuration:
sudo systemctl reload nginx
Certbot will now be able to find the correct server block and update it. Next, we will update your firewall to allow HTTPS traffic.
Allow HTTPS Access in Firewall
Previously, we configured the
ufw firewall on your server to allow
HTTP traffic. To additionally let in
HTTPS traffic, we need to allow the
Nginx Full profile and then delete the redundant
Nginx HTTP allowance.
Here is the command to allow Nginx Full:
sudo ufw allow 'Nginx Full'
And here is the command to delete the redundant
Nginx HTTP profile:
sudo ufw delete allow 'Nginx HTTP'
We're now ready to run Certbot and fetch the
Get The SSL Certificates From Certbot
Certbot provides a variety of ways to obtain
SSL certificates, through various plugins. The Nginx plugin will take care of reconfiguring Nginx and reloading the config whenever necessary.
To get SSL certificates for your
www.example.com URLs, use this command (make sure to use your URLs):
sudo certbot --nginx -d example.com -d www.example.com
This runs Certbot with the
--nginx plugin, using
-d to specify the names we'd like the certificate to be valid for.
If this is your first time running Certbot, you'll be prompted to enter an email address and agree to the terms of service.
After doing so, Certbot will communicate with the Let's Encrypt server, then run a challenge to verify that you control the domain you're requesting a certificate for.
If that's successful, 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 cancel):
Select your choice then hit
ENTER. The configuration will be updated, and Nginx will reload to pick up the new settings.
Your site is now being served over
Enter your domain into your browser's address bar and check it out:
Your certificates are now downloaded, installed, and loaded. And notice that your website is now being served over
You can test your servers
SSL rating using SSL Labs Server Test.
Verify Certbot Auto-Renew
Let's Encrypt's certificates are only valid for 90 days. This is to encourage users to automate their certificate renewal process. The Certbot package we installed takes care of this for us by running
certbot renew twice a day via a
systemd timer. On non-systemd distributions, this functionality is provided by a script placed in
/etc/cron.d. This task runs twice a day and will renew any certificate that's within thirty days of expiration.
To test the renewal process, you can do a dry run with Certbot:
sudo certbot renew --dry-run
If you see no errors, you're all set.
When necessary, Certbot will renew your certificates and reload Nginx to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.
Now we're ready to deploy your Create-React-App application.
Step 5 - Create and Deploy a Create-React-App Website
After following the previous steps, you should now have a web server running with
SSL certification. Now you can deploy your Create-React-App to the server and replace the default HTML Nginx displays.
Update Nginx Configuration
By default, Nginx is configured to serve documents out of a directory at
/var/www/html. To have Nginx serve a different site instead, you need to create your own directory within
/var/www for your site. The actual web content will be put in an HTML directory within this directory.
To create this directory (replace
example.com with your domain):
sudo mkdir -p /var/www/example.com/html
-p flag tells mkdir to create any necessary parent directories along the way.
Now that we have the directory, you need to reassign ownership of the web directories to the normal user account. This will let you write to them without
You can use the
$USER environmental variable to assign ownership to the account that you're currently signed in on (make sure you're not logged in as
root). This will allow you to easily create or edit the content in this directory:
sudo chown -R $USER:$USER /var/www/example.com/html
The permissions of your web roots should be correct already if you have not modified the umask value, but you can make sure by typing:
sudo chmod -R 755 /var/www
The directory structure is now configured and you can move on.
Create a Sample Page For Your Website
Now that the directory structure is set up, let's create a default page for your website so that it will have something to display.
index.html file in the directory you just created:
Inside the file, create a really basic HTML file. It will look like this:
<html> <head> <title>Welcome to Example.com!</title> </head> <body> <h1>Success! The example.com server block is working!</h1> </body> </html>
Save and close the file when you are finished.
Tell Nginx to Serve The New Html File
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.
To do this, open the default Nginx configuration file with
sudo nano /etc/nginx/sites-available/default
You need to change the document
root, specified by the
root directive in the file. Change that line so it points to the directory you created for your site:
Everything else can be kept the same. Save and close the file when you are finished.
Next, test to make sure that there are no syntax errors in any of your Nginx files:
sudo nginx -t
If no problems were found, restart Nginx to enable your changes:
sudo systemctl restart nginx
Nginx should now be serving the new HTML page you created.
Visit your domain in your web browser:
You should see a page with these words:
If the site works, you have successfully configured Nginx to serve any website that is placed in the
Deploy a Create-React-App Website to Your Server
Your Nginx web server is now ready to host whatever html files you give it. All you need to do is replace the files in
/var/www/example.com/html with new content.
Generate a Create-React-App Website (on your local machine)
We'll use Create-React-App to build and deploy a React website. It's an open-source project that makes building React web applications a breeze.
On your local machine, you'll need to have Node
8.16.0 or Node
10.16.0 or later version installed.
To create a new Create-React-App application, use one of the three commands below:
npx create-react-app your-site
npm init react-app your-site
yarn create react-app your-site
Test the App on Local Host
Now that your application has been built, let's test the site locally before it's deployed to your server. Inside the newly created project, you can run some built-in commands.
In the terminal window, move into your project folder with the command:
Then, run this command to run the application:
When the application is done compiling, you should see a similar message in your terminal:
Compiled Successfully! You can now view your-site in the browser. Local: http://localhost:3000/ On Your Network: http://192.168.42.125:3000/ Note that the development build is not optimized. To create a production build, use yarn build.
Your application is now running and you can view it in your browser:
Deploy Website to Your Server
Your application is ready to deploy onto your server. All we need to do is build your Create-React-App and copy the files from your local machine to the
/var/www/example.com/html directory on your DigitalOcean server.
First, let's build your application on your local machine:
npm run build
This builds the app for production and generates a
build folder. It correctly bundles React in production mode and optimizes everything for the best performance.
Your app is now ready to be deployed. Let's copy the
build folder across to the
/var/www/example.com/html directory you created on your server. In a terminal window and in the root directory of your project, run this command:
scp -r ./build/* user@server_ip_address :/var/www/example.com/html
Make sure you replace
example.com with your server information.
Go to your website and visit your website:
You should now see this or something similar when you visit your website in the browser:
Deploying Website Changes to Your Server
You've successfully created a live website! But now you want to make changes to the default Create-React-App application and deploy the changes. A simple
npm script in your
package.json file can achieve this.
First, open the
package.json file in your favorite text editor.
"scripts" section of the JSON, add this line of code:
"deploy-production": "react-scripts build && scp -r ./build/* user@server_ip_address:/var/www/example.com/html"
Make sure you replace
example.com with your server information.
Once you have added the line, your
package.json file should look similar to this:
npm run deploy-production script is called, it will generate a
build folder and copy the files to your server.
Run this command in the root of the Create-React-App directory:
npm run deploy-production
Any changes you made to your site should now be visible.
Congratulations! You now have a Create-React-App website running in production with
SSL Encryption! Go build something cool!
Thanks for reading and happy coding!