Deploy a MERN Project on AWS EC2

Initially, when I started developing MERN Projects, my question was how to showcase them to recruiters, friends, classmates, or anyone.

After some research, I found that AWS EC2 is the most straightforward way to do this, and it’s almost free under the free tier. This guide walks you through the full process — from pushing code to GitHub to accessing your project via a domain.

Prerequisites

Before starting, make sure you have:

  • A MERN project structured with client/ and server/ folders at the root
  • A GitHub account
  • An AWS account (see AWS Account Creation and Setup if you haven’t done this yet)
1. Push code to GitHub
  • Push your project to a public GitHub repository so it can be cloned directly on the server.

  • Run these commands from the root directory of your project (outside client/ and server/):

Copy to clipboard
git init .
git remote add origin [replace-github-repo-url]
git add .
git commit . -m "Initial Commit."
git push -u origin main
2. Launch an EC2 Instance
  • Go to AWS Console, search for “EC2”, and navigate to it.
  • Click Launch Instance.
  • Name the instance (for easier identification later).
  • Choose the latest Ubuntu AMI.
  • Create and download a .pem key — you’ll need this to SSH into the instance.
  • Increase storage from 8GB to 30GB if your project is media-heavy (30GB is the free-tier max).
  • Click Launch.

 

3. Configure Security Group (Inbound Rules)

This step is commonly missed and causes the project to be inaccessible after deployment.

In the EC2 dashboard, go to your instance → Security tab → click the security group → Edit Inbound Rules. Add the following:

TypeProtocolPortSource
HTTPTCP800.0.0.0/0
HTTPSTCP4430.0.0.0/0
SSHTCP22Your IP

Without ports 80 and 443 open, Nginx cannot serve traffic to the public.

4. Connect to the EC2 Instance

Open a terminal in the folder where you saved the .pem key. On Windows, type cmd in the folder address bar to open Command Prompt there.

Copy to clipboard
ssh -i [saved_file_name].pem ubuntu@[ec2_instance_public_ip]

Once logged in, update all system packages:

Copy to clipboard
sudo apt update
sudo apt upgrade -y
5. Install Node.js

Node.js and npm are not pre-installed on Ubuntu. Install them using Nodesource distributions.

Copy to clipboard
sudo apt-get install -y curl
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v

Verify the installation:

Copy to clipboard
node -v
npm -v
6. Clone and Set Up the Project
Clone the Repository
Copy to clipboard
git clone [github_repo_url]
Install Dependencies
Copy to clipboard
cd ./[Folder_Name]
cd ./server && npm install
cd ../client && npm install

Add .env files to both client/ and server/ with the required environment variables.

Build the Frontend

If your React project was set up with Vite, the build command compiles everything into a dist/ folder that Nginx will serve as static files.

Copy to clipboard
cd ./client
npm run build
7. Run the Server with PM2

PM2 is a process manager for Node.js. Without it, your server stops as soon as you close the SSH session. PM2 keeps the process running in the background and restarts it automatically if it crashes.

Install PM2
Copy to clipboard
npm install -g pm2
Start the Server
Copy to clipboard
cd ../server
pm2 start server.js --name mern-project
To make PM2 restart on system reboot:
Copy to clipboard
pm2 startup
pm2 save
8. Set Up Nginx as a Reverse Proxy

Nginx acts as the entry point for incoming traffic. It routes requests to either the React frontend (static files) or the Express backend (via proxy), based on the domain.

Install Nginx
Copy to clipboard
sudo apt install nginx -y
Create Config for the Frontend
Copy to clipboard
cd /etc/nginx/sites-available
sudo nano ui-mern.conf
Copy to clipboard
server {
    server_name [your_frontend_domain];
    root /home/ubuntu/[FolderName]/client/dist/;

    location / {
        index index.html;
        try_files $uri $uri/ /index.html;
    }
}
Create Config for the Backend API
Copy to clipboard
sudo nano api-mern.conf
Copy to clipboard
server {
    listen 80;
    server_name [your_api_domain];

    location / {
        proxy_pass http://127.0.0.1:[SERVER_PORT];
        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;
    }
}
Enable the Config and Restart Nginx
Copy to clipboard
sudo ln -s /etc/nginx/sites-available/ui-mern.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/api-mern.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Your project is now accessible via the domains you configured.

To add HTTPS, follow the steps in Install SSL Certificates on Ubuntu with Certbot.

Conclusion

Deploying a MERN project on AWS EC2 involves a few moving parts — GitHub, EC2, Node.js, PM2, and Nginx — but each one has a clear role. Once you’ve done it once, the process becomes straightforward. The free-tier setup is enough to host side projects, portfolio pieces, or anything you want to share publicly.