In this article, we're going to walk you through how to deploy a React application to a Vultr VPS (Virtual Private Server).

We'll also show you how to set up a custom domain, give it SSL/HTTPS encryption using Certbot and Let's Encrypt, create a React application using the Create-React-App framework, and host your website with a Nginx web server.

The last thing we'll cover is how to deploy any code changes to your website for when you add new content and features to your website.

Let's get started!

Table of Contents

  1. Set Up & Configure a Server
  2. Configure a Domain Name
  3. Install & Configure Nginx
  4. Configure HTTPS/SSL Encryption
  5. Create and Deploy a React Website

Step 1 - Set Up & Configure a Server

Before we can do anything, we need to set up and configure a VPS (Virtual Private Server) in the cloud to host our React application on.

There are a lot of companies that provide this service, but we'll use Vultr. You can use any other VPS service provider you wish, but some of the steps in this tutorial will be slightly different for you.

Create New Server on Vultr

To start, you need to create an account on Vultr or login to an account you've already created in the past.

For a FREE $50 CREDIT, use this link:

Vultr Website Signup Page Screenshot

They will ask you for a credit card, but you can cancel anytime before you exceed the $50 credit balance.

Make sure you have the I just want to link my credit card -$0.00 deposit checkbox checked. This will ensure your credit card doesn't get charged until you want it to.

Vultr Billing Page Screenshot

You should have an account created (or logged into a pre-existing one) with a free $50 credit to play around with.

We can now move to the next step.

Deploy New Instance on Vultr

In this article, we'll be using a Ubuntu server to host our applicaton on.

To create your Ubuntu server, go to the Products section and then to the Deploy New Instance page (link to page).

There are a ton of options on this page. So, let's go through each one.

Server Type

The first option is the type of server you want to use.

For the purpose of this article, we will be using the Cloud Compute server type.

So, choose the Cloud Compute option.

Vultr Deploy Type of Server

Server Location

Next, they let you choose where your server will be physically located.

Choose the location closest to where your users live to optimize the speed of your website or select whichever one you wish.

Vultr Deploy Server Location Screenshot

Server Operating System

Then you get to choose the operating system of your server.

They offer a lot of options in this department. But, we'll be using Ubuntu for this article.

Select the Ubuntu operating system and the distribution version you want to use (any option will work).

Vultr Deploy Server Operating System

Server Size

And then choose the size of your server.

For this tutorial, any size larger than the $2.50/month version will work. The smaller version only supports the IPv6 protocol and we'll need our server to support the IPv4 protocol later on when we set up your custom domain.

For more information on the differences between IPv4 and IPv6.

Vultr Deploy Server Size

Server Additional Options

After choosing the server size, there are three sections that you can leave blank:

  1. Additional Features
  2. Startup Script
  3. SSH Keys
Vultr Deploy Server Additional Options

Server Name & Deploy Server

In the last section, pick a hostname and label for your server. These values will only be visible to you.

When you're finished, click the Deploy Now button to tell Vultr to begin spinning up your new server.

Deploy a Server on Vultr Screenshot

You've successfully spun up a brand new server!

It may take a few minutes for Vultr to finish the process of spinning the server up. When that process is done, it'll be available for you to use.

In the next step, we'll start the initial configuration process for your new server.

Obtain Server IP Address & Root Password

To set up our server, you'll need both the IP address of the server and the private key (password) for the root user's account.

To obtain this information, go to the Products page and click on your new server. This will take you to the Server Information page for your server.

At the bottom of the page, you'll find the IP Address, Username, and Password for your server (red box in the image below).

Vultr Server Info Page Screenshot

Login as Root

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 highlighted word with your server's public IP address):

      ssh root@server_ip_address

Accept the warning about host authenticity, if it appears, and provide your root password. If it's your first time logging into the server with a password, you will also be asked to change the root password.

The root user in a Linux environment has very broad privileges and, for that reason, you are discouraged from using it on a regular basis. 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 the highlighted word with your username):

      # adduser bob

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, let's add your new user to the sudo group.

As root, run the following command to add your user to the sudo group (substitute the highlighted word with your username):

      usermod -aG sudo

Now your user can run commands with root privileges!

The next server setup steps 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 our server's security by requiring a private SSH key to login in.

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

Press ENTER to accept the file name and path.

Next, you'll be prompted to enter a password to secure the newly created key with. You can either create a password or leave it blank. This generates a private key, id_rsa, and a public key,, 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.

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 the highlighted words with your username and server public IP address):

      ssh-copy-id bob@server_ip_address

You will be asked for the user's password. Then, 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.

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 (

      cat ~/.ssh/

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 localuser@machine.local

Select the public key, and copy it to your clipboard.

To enable the use of 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 the highlighted word 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 .ssh called authorized_keys with a text editor. We will use nano to edit the file:

      nano ~/.ssh/authorized_keys

Now insert your public key (which should be in your clipboard) by pasting it into the editor.

Hit 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 root user:


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.

Only follow this step if you installed a public key in the last step. Otherwise, you'll lock yourself out of the server.

To disable password authentication, follow these next steps.

As the root user or new sudo user on your 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:

      PasswordAuthentication no

Save and close the file using the method: CTRL-X, then Y, then ENTER).

To reload the SSH daemon and put our 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

On your local machine, log in to your server using the new account that we created. Use the following command:

      ssh bob@server_ip_address

Once authentication is provided to the server, you will be logged in as your new user.

Basic Firewall Set Up

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

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

Press y and then ENTER to proceed. You can see that SSH connections are still allowed by typing:

      sudo ufw status

That was the last step in the initial setup for our server.

In the next section, we'll configure your domain name to point at your new Vultr server.

Step 2 - Configure a Domain Name

To setup a domain, we need to do two things:

  1. Purchase a domain name from a domain name registrar.
  2. Setup the DNS (Domain Name System) records for your domain by using Vultr's DNS hosting service.

Vultr is not a domain name registrar, but they do provide a DNS hosting service.

Before proceeding to the next step, make sure you have purchased a domain name from a service like GoDaddy, namecheap, HostGator,, or another registrar.

Point to Vultr Nameservers from Your Domain Registrars

To use the Vultr DNS, you'll need to update the nameservers used by your domain registrar to point at Vultr's nameservers instead.

For example, to update the nameserver settings for Namecheap, follow the steps below.

Sign in to your Namecheap account, then click Domain List in the left-hand column.

You'll be presented with a dashboard listing all of your domains. Click the Manage button of the domain you'd like to update.

Namecheap domain configuration.

In the Nameservers section of the resulting screen, select Custom DNS from the dropdown menu and enter the following nameservers:


It should look something like this:

Namecheap domain configuration.

Click the green checkmark to apply your changes.

Now you're ready to move on to connecting the domain with your server in the Vultr 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.

Those steps will be similar if you're using a different registrar than Namecheap.

Configure DNS

Now we need to add the domain to Vultr and point it to the server we spun up previously. When that's set up, Vultr will forward HTTP requests to that domain to the IP address for your server.

To do this, first go to the DNS section of your Vultr account (link to page) and click on the Add Domain button to navigate to the page where you can add a new domain (link to page).

Vultr Add Domain Page Screenshot

On that page, there's a form with two fields you need to fill out.

The first is your domain. Add your domain without the www in front (i.e.

And then add the IP address of the server you created earlier.

Submit the form by pressing the Add button when you're done.

This will forward you to a page with a list of DNS records for the domain you just created.

By default, Vultr adds an A record for the name. But you'll need to add another A record for the www version of your domain so that is handled correctly as well.

When you're done adding records to the table, it should look something similar to the screenshot below:

Vultr DNS Settings Screenshot

These settings may take several hours to update as both your domain registrar and Vultr need to be communicating with each other correctly and sharing the correct data.

Step 3 - Install & Configure Nginx

Once your domain is pointing to your server, it's time to install Nginx and configure the server to host web content.

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 installed and configured on your server!

Install Nginx

Nginx is available in Ubuntu's default repositories, so installation is pretty straightforward.

Run the following command to update your local apt package index so we have access to the most recent package lists:

      sudo apt-get update

Then, you can install Nginx along with any other required dependencies:

      sudo apt-get install nginx

When that's done installing, you can move onto the next section.

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

There are three profiles available for Nginx:

  • Nginx Full: Opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • 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 80. When we setup SSL Encryption later on, we'll change these settings.

You can enable this by typing:

      sudo ufw allow 'Nginx HTTP'

You can verify the change with this command:

      sudo ufw status

You should now see Nginx HTTP added to that outputted list.

Check 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


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

Default Nginx html page.

Congratulations! You now have a web server running!

In the next step, we'll configure SSL certificates for your domain.

Step 4 — Configure HTTPS/SSL Encryption

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.

Install Certbot

The first step is to install the Certbot software on your server.

First, add the repository:

      sudo add-apt-repository ppa:certbot/certbot

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

      . . .
      . . .

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

You'll need to adjust your ufw settings to allow HTTPS traffic.

To let in HTTPS traffic, you can allow the Nginx Full profile and then delete the redundant Nginx HTTP profile allowance. Run these two commands:

      sudo ufw allow 'Nginx Full' && sudo ufw delete allow 'Nginx HTTP'

We're now ready to run Certbot and fetch the SSL certificates.

Get the SSL Certificate 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:

      sudo certbot --nginx -d -d

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 HTTPS! 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 HTTPS.

You can test your servers SSL rating using the SSL Labs Server Test, you should receive an A grade.

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.

Step 5 - Create and Deploy a React Website

After following the previous steps, you should now have a Nginx web server running with HTTPS/SSL encryption.

Now you're ready to deploy a React application to the server and replace the HTML code Nginx displays by default.

First, let's update the Nginx configuration to display some custom HTML. After that, we'll use the Create-React-App framework to easily create a React application and deploy it to the server.

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 our site. The actual web content will be put in an HTML directory within this directory.

To create this directory:

      sudo mkdir -p /var/www/

The -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 sudo.

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/

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.

Create an index.html file in the directory you just created:

      nano /var/www/

Inside the file, create a really basic HTML file. It will look like this:

        	<title>Welcome to!</title>
        	<h1>Success! The server block is working!</h1>

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/ 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 nano:

      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 the directory you created for your site:

      root /var/www/;

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 both of your domain names.

Test the Results

Now that you are all set up, you should test that your server is functioning correctly. You can do that by visiting your domain in your web browser:


You should see a page with these words:

Html success.

If the site works, you have successfully configured Nginx to serve custom HTML instead of their default content.

Deploy Create-React-App Website to 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/ with new content.

Generate a Create-React-App Website (on your local machine)

In this tutorial, we will be using Create-React-App to build and deploy a website. It's an open-source project that makes building react web applications easy.

If you already have a Create-React-App application built and ready to go, you can skip this step.

On your local machine, you'll need to have Node 8.10.0 or later installed.

To create an app, use one of the following methods:


      npx create-react-app your-site


      npm init react-app 


      yarn create react-app 

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

      cd your-site

Then, run one of the two following commands to run the application:


      npm start


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:
      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 into the /var/www/ directory on your server.

First, let's build your application on your local machine using one of these commands:


      npm run build


      yarn 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/ directory you created on your server. In a terminal window and in the root directory of your project, run this command:

      scp -r ./build/* bob@server_ip_address :/var/www/

Make sure you replace bob, server_ip_address, and with your server information.

Open your browser and visit your website:


You should now see this or something similar when you visit your website in the browser:

React app view in 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 those changes for the world to see. A simple npm script in your package.json file can achieve this.

First, open the package.json file in your favorite text editor.

In the "scripts" section of the file, add this line of code:

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

Make sure you replace user, server_ip_address, and with your server information.

Once you have added the line, your package.json file should look similar to this:

Package.json file viewed in text editor.

When the npm run deploy-production script is called, it will generate a build folder and copy the files to your server using the scp -r command.

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.

That was the last step in this article.


Congratulations! You now have a Create-React-App website running in production with a custom domain and HTTPS/SSL encryption! And you also know how to deploy changes to your website whenever you need to.

Thanks for reading and happy coding!