# Hosting a react app to EC2 using Nginx with SSL certificate

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](https://cdn.hashnode.com/res/hashnode/image/upload/v1631486265637/sd4yY3zMt.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](https://cdn.hashnode.com/res/hashnode/image/upload/v1631445281044/jUbY6kFbU.png)

Create the instance and login using the ssh connection.

## Install NGINX

First, become a superuser,

```bash
sudo su
```

Update the package list and install `NGINX`,

```bash
sudo apt update
sudo apt install nginx
```

We can verify `NGINX` status,

```bash
service nginx status
```

If the `NGINX` is stopped, we can start by,

```bash
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,

```bash
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](https://github.com/nvm-sh/nvm).

Verify `Node.js` and `npm` is installed by,

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

Now clone the react app,

```bash
git clone you_app_git_link
```

Install the dependency and build the app.

```bash
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](https://cdn.hashnode.com/res/hashnode/image/upload/v1631445331803/Nv9vfZ7TP.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`,

```bash
cd /etc/nginx/sites-enabled
```

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

```bash
rm default
```

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

```bash
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,

```bash
nginx -t
```

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

```bash
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](https://www.openssl.org/) to generate the free SSL certificate.

To create the SSL certificate,

```bash
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,

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

Certificate reference file will be,

```txt
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,

```bash
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`,

```nginx
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,

```nginx
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,

```bash
service nginx restart
```

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

![inbound rules.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1631445368159/uuuInPiFk.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](https://serverspace.io/support/help/how-to-get-lets-encrypt-ssl-on-ubuntu/)
2. [NGINX Documentation](https://docs.nginx.com/nginx/deployment-guides/amazon-web-services/ec2-instances-for-nginx/)
3. [Ubuntu Documentation](https://ubuntu.com/tutorials/install-and-configure-nginx#1-overview)
4. [Digital Ocean Blog](https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04)
