Deploy a React App with an Express Server on AWS EC2
By: Zhe Cai
Tags: React, AWS, Deployment, Express

Photo by Glenn Carstens-Peters on Unsplash

In this tutorial, I will walk you through a fairly complex AWS deployment setup from scratch. I will assume you could already run your React app on your localhost. Also, I will assume your backend part is implemented based on Express and you can access your database from the EC2 instance.

Prerequisites

AWS EC2

The very first step is to have an EC2 instance in your AWS account. When the instance is successfully set up, the next step is to edit the inbound rules so that you can access your website once it is eventually deployed. For example, if your final web app could be accessed by HTTPS, then you need to open port 443 of TCP protocol. The corresponding source should be set to Anywhere so that anyone can visit your website.

The following steps include modifying the code. You could do it on your PC then upload to the EC2 instance or do it directly on the instance. It’s totally up to you.

CORS

When the whole application runs successfully on the localhost, three parts — the frontend, the backend, and the browser all run on the localhost. Now if the application is deployed on an EC2 instance, at least the browser will not be running on the localhost anymore, supposing both frontend and backend are deployed on the same instance and you are not opening a browser on the EC2 instance. One important thing you should know is that the frontend code is running on the browser. Therefore, you now need to replace all the fetch requests to localhost with something else. The replacement would be the IP Address or the Domain Name that your backend runs on. For instance, if your backend runs on the same EC2 instance with the IP 111.111.111.111 . Now all fetch requests in your frontend code should look like

fetch("http:111.111.111.111:{port}/***/***")

Now we encounter the first big issue. We send requests from the domain where the browser runs on to the domain where the backend code runs on, which is restricted by default in Express. Fortunately, we have a package named cors (Cross-Origin Resource Sharing), which aims to solve this tricky problem. Now we should modify the backend code like this

HTTPS (optional)

Why HTTPS

HTTPS has numerous advantages over HTTP. However, if it’s not so crucial for your web application to have a high-security level for any reason, you can skip this section. The main reason why our app needs HTTPS is that we incorporate Auth0. Auth0 must run a secure origin. In most browsers, secure origins are origins that match at least one of the following (scheme, host, port) patterns:

(https, *, *)

(wss, *, *)

(*, localhost, *)

(*, 127/8, *)

(*, ::1/128, *)

(file, *, —)

Configure SSL/TLS on EC2

AWS docs have a detailed tutorial about how to configure SSL/TLS on EC2 so I won’t talk too much here. The tutorial can be found here.

Certificate

There are multiple ways to get a Domain Name and a CA-signed Certificate. If you are a student, Github Student Developer Pack partners with several domain-name vendors that provide these services free for one year.

Normally, we put the certificate files in the folder /etc/pki/tls/certs/ and put the key files in the folder /etc/pki/tls/private/ . Afterward, we need to edit /etc/httpd/conf.d/ssl.conf to reflect your new certificate and key files, as the AWS tutorial suggests:

Provide the path and file name of the CA-signed host certificate in Apache’s SSLCertificateFile directive: SSLCertificateFile /etc/pki/tls/certs/custom.crt If you received an intermediate certificate file (intermediate.crt in this example), provide its path and file name using Apache’s SSLCACertificateFile directive: SSLCACertificateFile /etc/pki/tls/certs/intermediate.crt Provide the path and file name of the private key (custom.key in this example) in Apache’s SSLCertificateKeyFile directive: SSLCertificateKeyFile /etc/pki/tls/private/custom.key

Config in Development Environment

Now we are going to test if the certificate works. We could create a file named .env in the client folder. In that file, we add these lines:

SSL_CRT_FILE=path/to/certificate/custom.crt

SSL_KEY_FILE=path/to/key/custom.key

Besides, we need to modify the scripts.start code in package.json like this to enable HTTPS.

"start": "HTTPS=true react-scripts start"

Mix Contents

As you start your application, you might notice something like this in the browser console.