Using NGINX to serve React Application (Static vs Reverse Proxy)
Tags: react, javascript, programming
Published: 2023-04-19 09:08:05

_To read more articles like this, [visit my blog](https://www.mdfaisal.com/blog)_

So you have built an awesome React application. How can you show it to people? A good thing about react is it generates static assets. So you can serve it just like any other static website.

Today we will see how to serve our react app using Nginx in the Ubuntu server. NGINX is a powerful tool we can use with React to leverage its awesomeness.

Our target server can be any Ubuntu server instance like EC2 Instance in AWS or a Droplet in Digital Ocean, or even your local machine.

There are many tutorials on setting up your server in aws or digital ocean. I am not going over that. We will keep our focus on the setup of Nginx with React.

Imagine you already have an EC2 instance or Digital Ocean droplet running. Now ssh into your machine ….

## STEP 1: Install Node and NPM

Okay, so now you have your project inside your machine, now install node and npm. First, enable the node source.

```
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
```

then install node

```
sudo apt install nodejs
```

Check node version

```
node --version
```

Check npm version

```
npm --version
```

## STEP 2: Install NGINX

Run the following command.

```
sudo apt install nginx
```

Check if it’s installed correctly by using.

```
nginx -v
```

At this moment, if you go to your server's IP address, it will look something like this.

![nginx is installed succesfully](https://cdn-images-1.medium.com/max/3584/1*jXJqHa3xihqsvgA3zOthRQ.png)

Now enable Nginx so that it automatically starts if the server restarts.

```
sudo systemctl enable nginx
```

Or You can check the status of your Nginx by typing.

```
systemctl status nginx
```

Which will give the output below

![Nginx is up and running](https://cdn-images-1.medium.com/max/4912/1*wmjACMMKoRop_MQGAT_DwA.png)

## STEP 3: Get your project into your server

Get your project into your machine. If you are using HTTPS, it will look like

```
git clone your_repository_address
```

## Step 4: Build your project

Go into your projects root directory, then build your react app as usual

```
npm install
npm run build
```

These commands will create an optimized production build and put the resources under the build folder. If you go inside your build folder, it will look something like this.

![Contents of build folder](https://cdn-images-1.medium.com/max/4328/1*F51waZcedzpLTOyKrXVqBg.png)

Here we have our index.html file and minified js bundle, which can be used to serve our website.
>  TIP: You can avoid the whole building process inside your server and build the project locally and transfer them into your remote machine using tools like scp. As we are serving static files, it will be enough.

## Step 5: Copy Build folder projects into var/www/HTML

Now go back to the root folder of our machine, where the result of the **ls** command will give us the following output.

![root folder of our machine](https://cdn-images-1.medium.com/max/4724/1*fq6zbuFrvh8uMwvTW3NiEA.png)

Now copy the contents of the build folder into **var/www/html**. It’s optional. You can put your files anywhere you like. you can create a separate folder for each project and keep the generated assets there.

For simplicity, we are keeping them under var/www/html/build. So it will be our root.

```
sudo cp -r /home/ubuntu/your-project-folder/build/. /var/www/html
```

## **STEP 6: Configure NGINX to serve static files**

Now we need to configure our Nginx to serve these files. Write the following commands. I am using nano here.

```
sudo nano /etc/nginx/sites-available/default
```

Then edit the commands so that the final contents of the file look like this.

![nginx configuration](https://cdn-images-1.medium.com/max/2000/1*Pt4oYA1zF1svX6ZP5urT3Q.png)

The contents are very straightforward here.

* We are listening to **port** 80

* **the root** will be the location where we put our static contents

* **index** will be our index.html file

* **server_name** will be our server's IP address. It can also be other domain names that you can use.

* inside **location** we can serve our static content like images or pdf etc. for now we are using it as fallback content.
Then save the file using the following commands. If you are familiar with `nano`, you know them already!


```
CNTRL + X
Y (for yes) 
Enter
```

Now we need to restart **NGINX** to see the results.

```
sudo service nginx restart
```

If we go to our server's IP address [http://your_ip_address_here], we will hopefully see our react app up and running.

## STEP 6 (alternative): Configure NGINX to work as a proxy :

Sometimes we run our react applications using packages like PM2 or forever. We run them using our node server that is built into create-react-app. But one problem is whenever we have to access that, we need to type in the port number into the address. For example, if we run our react app in this server on port 300 (the usual one), to access our site, we need to go to [http://your_ip_address_here](http://your_ip_address_here):3000 your browser. Nginx can solve this problem.

For this, we can run the following commands from inside our project's root directory to run the app. We are not going too deep into the topics here. To run our react app using forever, we can use the following command from inside our project.

```
forever start -c "yarn start" ./
```

or using pm2

```
pm2 start node_modules/react-scripts/scripts/start.js --name "your-project-name"
```

Now, if we visit the 
**[http://your_ip_address_here](http://your_ip_address_here):3000** address from the browser, we can see our app is up and running.

Now we will enable our firewall to block access to all the ports.

```
sudo ufw status  // it will say our firewall is inactive

sudo ufw enable  // it will enable our firewall

sudo ufw app list // it will list the apps 
```

If we check the status now, it will be active, But if we want to access our application, we won't be able to do it because the firewall will block us. We need to run the following command(s) to allow access.

```
sudo ufw allow 'Nginx HTTP'  // to allow HTTP only (enough for now)

sudo ufw allow 'Nginx HTTP'  // to allow https 

sudo ufw allow 'Nginx Full'  // to allow full nginx
```

Now visiting our server, we will not see our app running because we didn’t allow port 3000 to the outside world.

We need to configure our Nginx to forward port `80` to our `3000` port. To do that, we need to configure our Nginx again, just like before. This time the contents will be

![](https://cdn-images-1.medium.com/max/2000/1*9i5WGYfTTxMLrBeIIibE8g.png)

Save the file just like before.

Here we are using proxy_pass to say that we need to redirect the requests into port `80` to `localhost:3000`, where our application is running.

Cheers! Now we can visit our app on [http://your_server_ip_address](http://your_server_ip_address) without specifying the port at the end of the address!

## STEP 7: Adding SSL Certificate with LetsEncrypt

It is easy to attach a free SSL certificate for our site using Nginx. Run the following commands to install `certbot` in our ec2 instance.

```
sudo apt-add-repository -r ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
```

It will ask for your email, and you are done.

This certificate will be valid for 90 days. You have to run the following command to update your certificate.

```
certbot renew --dry-run
```

You have to add your IP address to your DNS server to take effect.

Now, if you go to [https://yourdomain.com](https://yourdomain.com), you will see that it is being served over HTTPS.

So that’s it for today. Happy Coding! :D

**Get in touch with me via [LinkedIn](https://www.linkedin.com/in/56faisal/) or my [Personal Website](https://www.mdfaisal.com/).**