Deploy a MERN application to AWS (EC2 Instance) using Nginx Server

Deploy a MERN application to AWS (EC2 Instance) using Nginx Server

What is MERN Application ?

MERN stands for MongoDB, Express, React, Node, after the four key technologies that make up the stack.

  • MongoDB - Document database (BSON object or Binary JSON)
  • Express - Open source Node.js web framework
  • React - A client-side JavaScript framework developed by Facebook
  • Node - Node.js is an open source server environment

What is EC2 service in AWS- amazon web service ?

Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides secure, resizable compute capacity in the cloud. It is designed to make web - scale cloud computing easier for developers.

What is NGINX server ?

NGINX is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. NGINX is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.

Deployment

We can deploy Mern Application with many ways. Two common ways are:

  • Deploy Frontend at different place and Backend at different place

  • Deploy the Frontend and Backend at same place ( Setting up proxy server)

In this post, we will follow second approach. We will create proxy to backend server and then deploy it to AWS using NGINX server.

Setting up proxy in Frontend

Suppose your Frontend (React app) is running on port 3000 and Backend is running on port 4001 . Then we have to add proxy on port 4001 for backend accessible.

Steps:

  • Open package.json file in your react app.
  • Paste "proxy": "localhost:4001" in last line of package.json file.

In my case package.json looks like:

{
  "name": "projfrontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "history": "^5.0.0",
    "query-string": "^6.13.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "3.4.1",
    "react-stripe-checkout": "^2.6.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "proxy": "http://localhost:4001"
}
  • Remove localhost:4001 at every place which you have wriiten at time of calling Backend API's. ( Hit API's link without localhost:4001 , As we have proxy to Backend).
export const createCategory = (userId, token, category) => {

    return fetch(`/api/category/create/${userId}`, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: `Bearer ${token}`
    },

    body: JSON.stringify(category)
  })
    .then(response => {

      return response.json();
    })
    .catch(err => console.log(err));
};

Creating a Production Build in React App

  • If you are using NPM , then hit command npm run build in React App. It will create optimize production build folder in your application. Now our Frontend is ready for deployment.

Creating Build Folder as a Public folder in index.js (App.js) file

  • In first step , copy build folder from frontend and paste it in Backend directory. It will never create mesh for giving path in index.js file.
  • Add following lines of code in index.js file.
// Making Build Folder as Public 
app.use(express.static(path.join(__dirname, 'build')));

app.get('/', function(req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

Setup your MongoDB database on cloud

you can put your mongoDB database on mongoDB Atlas . It will give 500MB free space. Paste secret token provided by mongoDB atlas at mongoDB connection in your backend file.

For more reference you can see github repo., link given at end of this post.

After following these steps push your all changes to github.

Setup The server on AWS

Now, we will make instance in EC2 service given by AWS and then we wil setup Nginx server.

  • Sign up to AWS (Amazon web serive)

  • Select EC2 service from the search box

  • Go to Instances section

  • Click on Launch Instances.

1.PNG

  • Select Ubuntu Server 20.04 LTS (HVM), SSD Volume Type server.

  • Click on Review and Launch

  • Click on Edit security groups

1.PNG

  • Add Rules shown in Following Image.

1.PNG

  • Click on Launch
  • Now aws will ask for Key-pair,which wil help to connect server to your remote system.
  • Select new key pair
  • Give key pair name and download the key-pair file (.pem file).
  • Click on Launch. within short time you will get status running of you server and will get public IP.

Connect server to your remote system

Window Users

  1. Install Putty on your system.
  2. Convert the .pem to putty .ppk file using Puttygen and save its private key.
  3. Open Putty
  4. Paste Public IP of your server (on Aws) to Host Name( Ip address in Putty)
  5. Open connection section in putty
  6. In Data section, add username ubuntu
  7. In Auth section, Browse the .ppk file saved by you.
  8. Click on Open , It will open your server on your remote system. Also, you can store this session with any name , so every time you don't need to fill all credentials.

Linux or Mac users

Copy the commad given in connect section of your aws server.

Install Required dependencies on your server by pasting following command in your terminal

curl https://gist.githubusercontent.com/cornflourblue/f0abd30f47d96d6ff127fe8a9e5bbd9f/raw/e3047c9dc3ce8b796e7354c92d2c47ce61981d2f/setup-nodejs-mongodb-production-server-on-ubuntu-1804.sh | sudo bash

Clone Project on your server by pasting following command

git clone "repo link"

Config NGINX server using following commands

  • Delete the default NGINX site config file with the command sudo rm /etc/nginx/sites-available/default
  • Launch the nano text editor to create an new default site config file with sudo nano /etc/nginx/sites-available/default

  • Paste following data in nano editor and save it.

server {
  listen 80 default_server;
  server_name _;

  # Backend
  location / {
    proxy_pass http://localhost:4001/;
  }
}
  • Save the file by pressing ctrl + x and selecting Yes to save.

  • Restart NGINX with the command sudo systemctl restart nginx

Starting the server using pm2 module

  • Go to your project directory and then go to backend directory.

  • Install Dependecies using npm install

  • Paste follwing command
npm install pm2
  • Paste following command
sudo pm2 start app/index.js

you will see following screen

1.PNG

You have deployed your MERN app successfully . Moreover you can add Elastic IP to your EC2 instance. your can add Domain name to your app using route53 service in Aws . You can protect you app form attacks using AWS Waf ( web application firewall).

Demo of Deployed Project

Thank you. Happy learning!!!

Did you find this article valuable?

Support Learn Code Online by becoming a sponsor. Any amount is appreciated!