5 simple steps (with screenshots) to deploy your MERN app

Nitin Garg
6 min readJul 14, 2021

MERN: Mongodb, Express, React and Nodejs. MERN stack is currently one of the hottest technologies available in the market. In this article I will very briefly discuss about deploying a MERN application.

To deploy our app we will user AWS EC2 with Ubuntu OS for hosting our app, Mongodb Cloud for hosting our database and nginx to reverse proxy traffic to our frontend and apis.

5 Steps in brief

  1. Launch AWS EC2 instance with Ubuntu 20.04 server image
  2. Launch MongoDB cluster or install MongoDB community version
  3. Install Nginx, git, nvm on the EC2 instance
  4. Clone express app repository and start app server using PM2.
  5. Build React project and deploy.

Step 1: Launch AWS EC2 instance with Ubuntu 20.04 server image

AWS is one of the biggest cloud service provider, its 1 year free trial is ideal for developers learning devops or for testing waters for your new Idea. Its fairly easy to launch an EC2 instance. To lauch an ec2 instance login to your AWS console, search for ec2 and lookout for the Launch Instance button.

Click on the button and select Ubuntu Server 20.04 LTS.

On the next page Select t2.micro (free tier eligible) or any other instance according to your use case. Keep clicking on Next (default settings are good enough for a general applications but you can change them according to you requirements) until you reach the “Configure security group” tab, click on the Add Rule, select http protocol, repeat for https protocol and them click on Review and Launch.

On the next page click on Launch. After clicking a popup will open, create a new key pair or use an existing key pair. Ensure that you have private key file for the key pair which you are using. After clicking on Launch Instance your EC2 server will be up and running.

Step 2: Launch MongoDB cluster or install MongoDB community version

Launching MongoDB cluster on MongoDB atlas is very simple so I won’t go in detail, MongoDB atlas offers a free tier which is more than enough for small applications to begin with.

To install MongoDB community server on Ubuntu VM we just created follow this tutorial by MongoDB.

Step 3: Install Nginx, git, nvm on the EC2 instance

Let me first introduce Nginx and why do we need it. Nginx is a webserver that can be used to serve static files, or it can be used to reverse proxy traffic to other application servers. Nginx can also be used as a load balancer for multiple instances of application server.

Why are we using Nginx ?

  1. We want to keep API and frontend files separate, to make deployment fast and simple, so traffic should be diverted accordingly.
  2. We don’t want to manage https config from our express application.
  3. We might want to instantiate more than 1 instance of our express application to improve performance.

You can read more about Nginx on the below article by Nginx team.

And an in depth explanation of why we need Nginx in this masterpiece:

To install Nginx, git execute following command on the VM.

sudo apt-get install nginx git

To install nvm execute bellow commands:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bashexport NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
nvm install v14.17.3

You might ask why we need nvm for ?

Full form of nvm is node version manager. You can use nvm to install different version of nodejs along with npm. This is one of the easiest way to properly install nodejs on linux.

OPTIONAL: I personally prefer vim over other text editors. Vim comes by default installed, but not with its latest version. To update vim use following command.

sudo apt-get install vim

Step 4: Clone express app repository and start app server using pm2.

Use git to clone your express app on the VM. Install PM2 on the VM using below command.

npm i -g pm2

In a brief PM2 is a daemon process manager that will help you manage and keep your application online 24/7. Visit PM2 official website for more info.

Step 5: Build React project and deploy.

Navigate to you react project and run below command in a terminal.

npm run build

If you are using env variables and want to change the variables according to different environments take a look at the env-cmd package.

While the build is in progress create a folder on the VM to keep build files in. After build is finished use scp command to move build files to the folder.

scp -r -i /home/user/ssh_keys/test.pem build/* ubuntu@x.x.x.x:/home/ubuntu/test-app-frontend

Replace x.x.x.x with ip of your instance.

An efficient method to automate build and transfer of build files is by using bash script, below is an example of the script.

#!/bin/shnpm run buildssh -i /home/user/ssh_keys/test.pem ubuntu@x.x.x.x 'rm /home/ubuntu/test-app-frontend/* -r; mkdir -p /home/ubuntu/test-app-frontend'scp -r -i /home/users/ssh_keys/test.pem build/* ubuntu@x.x.x.x:/home/ubuntu/test-app-frontendrm build -r

This script build the react app files, then removes existing files on the VM and copy the build files on the VM. Finally the script cleans the build folder ( this step can be omitted if required).

Configure Nginx to reverse proxy traffic to frontend files and api. We need to edit the Nginx congif file located at /etc/nginx. Following is an example of config file.

# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80 ipv6only=on default_server;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
location /api/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location / {
alias /home/ubuntu/test-app-frontend/;
index index.html;
try_files $uri $uri/ index.html =404;
}
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
}
}

In this config I have assumed that you have ssl certificate installed and managed by Certbot. Certbot can generate SSL certificate issues by lets encrypt and install them on its own for you.

With this we end this tutorial. All the best deploying your MERN application.

--

--