Deploy a MERN Project on AWS EC2
Prerequisites
Before starting, make sure you have:
- A MERN project structured with
client/andserver/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/andserver/):
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
.pemkey — 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:
| Type | Protocol | Port | Source |
|---|---|---|---|
| HTTP | TCP | 80 | 0.0.0.0/0 |
| HTTPS | TCP | 443 | 0.0.0.0/0 |
| SSH | TCP | 22 | Your 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.
ssh -i [saved_file_name].pem ubuntu@[ec2_instance_public_ip]
Once logged in, update all system packages:
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.
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:
node -v
npm -v
6. Clone and Set Up the Project
Clone the Repository
git clone [github_repo_url]
Install Dependencies
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.
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
npm install -g pm2
Start the Server
cd ../server
pm2 start server.js --name mern-project
To make PM2 restart on system reboot:
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
sudo apt install nginx -y
Create Config for the Frontend
cd /etc/nginx/sites-available
sudo nano ui-mern.conf
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
sudo nano api-mern.conf
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
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.