Deploy React Apps using Apache2, how and why?
Tags: react, javascript, devops, webdev
Published: 2021-10-03 11:23:12

In this article we will together go through the process of deploying front end applications to production environments ( specifically [React](https://reactjs.org/) applications ).

### How does the web work?
Before we dig into the actual steps needed to deploy React applications, let’s first think about how the web works in general.

When you visit a URL like this: `http://my-domain.com/user/profile`, you’re basically sending a request searching the web to find if there’s an [A record](https://support.dnsimple.com/articles/a-record/) for this domain linked to any IP address, aka server, and if it finds one, it sends this request to that server. But for this server to be able to handle that request, there needs to be some kind of software, from now on let’s call it a [web server](https://en.wikipedia.org/wiki/Web_server) to handle this request and get some response to send it back to you!

There are many web servers out there that you can use. For this article, we’ll focus on the configurations for [Apache2](https://httpd.apache.org/). Another popular option that can be used is [Nginx](https://www.nginx.com/), but the idea is exactly the same.

When this request reaches the web server, what happens is that the web server checks if this domain name ( in our case `http://my-domain.com` ) is configured to any directory/folder in this server ( in case of Apache2, the default root directory is `/var/www/html` ), and if so, it basically serves/displays the web application/hosted files on the path that you passed in the URL, `/user/profile`. Which means that this request will go to the files ( by default an index.html file ) in the `/var/www/html/user/profile` directory.

### Virtual Hosts
The way you configure the domain-names/directories mapping in Apache2 is by configuring what we call a [virtual host](https://httpd.apache.org/docs/2.4/vhosts/) in this path `/etc/apache2/sites-available/default`, which basically allows you to host multiple web applications on the same machine, each in a separate directory.

A basic Virtual Host will look like this:
```
<VirtualHost YOUR_IP_ADDRESS:80>
  ServerName www.my-domain.com
  ServerAlias my-domain.com
  DocumentRoot "/var/www/html"
  AllowOverride All
</VirtualHost>
```
This configurations basically mean that any incoming request to `YOUR_IP_ADDRESS`, on PORT `80` ( which is the default port for Apache2 ), will serve the files stored in the `/var/www/html` directory, following the URL that the user requested, from now on let's call it `Route`.
* Note that we had to add `AllowOverride All`, and that's necessary because we'll need to add an [.htaccess](#htaccess-file) file later on and this needs to be there for it work.
* You might find this property in your default configurations with `AllowOverride None`, you just need to change it to `All`, and remember to restart your Apache2 configurations by running this command `sudo systemctl apache2 restart`, or an equivalent command for your webserver, to restart your configurations.

###### HTTPs Configurations
If you want your application to run on https, you will also need to have another configuration files to handle your incoming secured requests, but that's out of the scope of this article.

I might post another article later on how you can create and maintain a self signed certificate using [let's encrypt](https://letsencrypt.org/).

For the sake of this article, we'll assume that your application is going to be hosted on the root folder of the server, aka the default configurations.

### Hosting Files
Once you configure your domain to point to your server and add your virtual hosts, then you can basically host any file of any extension on this server to be served using this domain.

One way to respond to a user who is sending the `/user/profile` request is to create a directory `/user/profile` in the root directory of this domain, and then create an `index.html` file in this directory. In this case, the content of this file will be served to the user.

But that's not why we're here! So let's talk about React deployment flow.

### React Deployment Flow

#### Build your app
To deploy a react application you'll first need to build your application, this might differ according to the way you structured your application. But regardless of how your app is configured, you should be able to run a similar command to `npm run build` command to build your app, which will give you the final build files in a folder called `build`, and those are the files that we need to deploy/upload to the web application path on the server ( in our case `/var/www/html/` ).

###### Two important points to notice here:

* in the `root` folder of your build folder you'll find an `index.html` file;
* if you open this file, you'll find in the `<head>` section one or more `<script>` tags that point to your React application code, including how you're handling your routes.


[Remember](#hosting-files) how we talked about hosting static files, specifically `index.html` files to the server? Keep that in mind for now.


#### Deploy your files
One of the ways you can use to upload your files to the server is using FTP ( File Transfer Protocol ) softwares, I usually use [FileZilla](https://filezilla-project.org/).

You might also be using docker or git to host your build files, and all you have to do at this point is to fetch the latest updates to your folder or re-run your docker image/container with the latest updates.


#### .htaccess file
Before we talk about this file and give an example of the minimal content you need to have for your app to work on Apache2 web server, let's first quickly remember the incoming request that we're trying to send to our server.

I'm assuming at the moment that:
* `/var/www/html/` folder is empty;
* you have a route in your React app that's called `/user/profile`;
* the incoming request is trying to reach the `/user/profile/` route.

But in fact, there's no directory path in our server that matches this route, so what will happen now if we don't have any instructions to our web server ( Apache2 ) to handle this incoming request, you'll definitely get a 404 Not Found error page!

That's why we need to add the [.htaccess file](https://httpd.apache.org/docs/current/howto/htaccess.html) to instruct Apache2 to basically redirect all the incoming requests to this folder to the index.html file, [which will know how to handle your request](#two-important-points-to-notice-here).


Finally, let's have a look on how the `.htaccess` file should look like at the minimal shape for your React application to work ( this piece of code is stolen from the official [React deployment page](https://create-react-app.dev/docs/deployment/), don't tell anyone! ):
```
    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [QSA,L]
```

By default, Apache2 will ignore all the `.htaccess` files. You will need to install [a module](http://httpd.apache.org/docs/current/mod/mod_rewrite.html) to tell Apache2 to enable overriding the directories configurations using .htaccess files. To do that, you just need to run this command `sudo a2enmod rewrite`. Don't forget to restart Apache2 for this configuration to take place. Simply run `sudo systemctl apache2 restart`.

And that's it! Now you have your application up and running on production.