Hosting a react app to EC2 using Nginx with SSL certificate

Hosting a react app to EC2 using Nginx with SSL certificate

Step by step guide to deploy a static site to VPS server.

Today, we are going to deploy a React app to the EC2 instance. The following process can be applied for any static site like Angular, Vue. As a proxy server, we will use NGINX server. Using OpenSSL, a self-signed SSL certificate will also be implemented.

aws-blogs.drawio (1).png

To host the app, we first need to set up a virtual server. As os in EC2 service, we will make use of Ubuntu OS.

ubuntu-ami.png

Create the instance and login using the ssh connection.

Install NGINX

First, become a superuser,

sudo su

Update the package list and install NGINX,

sudo apt update
sudo apt install nginx

We can verify NGINX status,

service nginx status

If the NGINX is stopped, we can start by,

service nginx start

Prepare the React App

In this case, you might want to bring your own react application from git. To do so, we must have the git installed in the system. We can install git by simply,

sudo apt-get install git-all -y

To build the react app, we should have the Node.js installed in the system. We will install Node.js using the nvm. To install nvm and your desired version of Node.js follow the instructions from nvm github page.

Verify Node.js and npm is installed by,

node -v # should output the node version
npm -v # should output the npm version

Now clone the react app,

git clone you_app_git_link

Install the dependency and build the app.

npm install
npm run build

The build/dist path will be required to configure the NGINX.

Configure NGINX

NGINX used to route the traffic through 80 port. To allow port 80 in the instance, update the security group.

inbound rules.png

Now if we access the http://instance_ip, we should see the default NGINX page.

To configure the react up, we have to create a config file in sites-enabled.

Go to sites-enabled config of NGINX,

cd /etc/nginx/sites-enabled

If there is a default config named default we can remove it,

rm default

Create a config file with any name, in this case, we can use the name client-config,

touch client-config

Our new config will be,

server {
    listen 80;
    server_name ip_of_the_ec2_instance;
    root path_to_react_build_directory_or_distribution_directory;
    index index.html; # react by default generate the file in the build directory
    location / {
        try_files $uri $uri/ =404;
    }
}

We can verify the NGINX syntax,

nginx -t

We have to restart the NGINX to make the new config effective,

service nginx restart

Go to the server ip or domain and verify the application is working perfectly.

Install Self Signed SSL Certificate

We will use the OpenSSL to generate the free SSL certificate.

To create the SSL certificate,

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

This will create a SSL certificate and put it in the /etc/ssl/certs/ directory.

Create a file in NGINX referencing these certificates,

sudo nano /etc/nginx/snippets/self-signed.conf

Certificate reference file will be,

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

For forward secrecy, we have to create a strong Diffie-Hellman group,

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

Now add the following snippet for HTTPS connection in the previous configuration file in /etc/nginx/sites-enabled/client-config,

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/self-signed.conf;
}

The final client-config file will be,

server {
    listen 80;
    server_name ip_of_the_ec2_instance;
    root path_to_react_build_directory_or_distribution_directory;
    index index.html; # react by default generate the file in the build directory
    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/self-signed.conf;
}

Restart NGINX server to make the HTTPS connection effective,

service nginx restart

To access the server with SSL connection, we have to enable port 443 in the security group.

inbound rules.png

Now if we go to the https://ip_or_domain_of_server we should see the application with secure connection.

References:

  1. Verify SSL Connection
  2. NGINX Documentation
  3. Ubuntu Documentation
  4. Digital Ocean Blog