Skip to content

Pratham-1229/Cloud_computing_projects

Repository files navigation

πŸš€ MERN Stack Application β€” AWS EC2 Deployment Guide

A complete step-by-step guide to deploying a full-stack MERN (MongoDB Atlas, Express, React, Node.js) application on an AWS EC2 instance with Nginx as a reverse proxy and PM2 as a process manager.


πŸ“‹ Table of Contents


πŸ›  Tech Stack

Layer Technology
Frontend React.js
Backend Node.js + Express.js
Database MongoDB Atlas (Cloud)
Process Manager PM2
Web Server / Proxy Nginx
Cloud Platform AWS EC2 (Ubuntu / Amazon Linux 2)
Auth JWT (JSON Web Tokens)

βœ… Prerequisites

Before you begin, make sure you have:

  • An AWS account with EC2 access
  • A MongoDB Atlas account with a cluster created
  • Your project pushed to a GitHub repository
  • A .pem key pair file downloaded from AWS
  • EC2 Security Group configured with these inbound rules:
Type Protocol Port Source
SSH TCP 22 Your IP
HTTP TCP 80 0.0.0.0/0
Custom TCP TCP 5000 0.0.0.0/0

☁️ MongoDB Atlas Setup

1. Go to https://cloud.mongodb.com β†’ Create free account
2. Create a FREE cluster (M0 Sandbox)
3. Database Access β†’ Add DB User (username + strong password)
4. Network Access β†’ Add IP Address β†’ Allow from Anywhere (0.0.0.0/0)
5. Connect β†’ Drivers β†’ Copy your connection string

# Your connection string will look like:
mongodb+srv://<username>:<password>@cluster0.xxxxx.mongodb.net/<dbname>?retryWrites=true&w=majority

πŸ“Œ Phase 1 β€” EC2 Instance Setup

# SSH into your EC2 instance
ssh -i your-key.pem ubuntu@<YOUR-EC2-PUBLIC-IP>

# Switch to superuser
sudo su

# Update system packages
apt update -y           # Ubuntu / Debian
# OR
yum update -y           # Amazon Linux

# Verify your current directory and user
pwd
whoami

# Install Node.js 18
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
sudo apt install -y nodejs     # Ubuntu
# OR
sudo yum install -y nodejs     # Amazon Linux

# Install Git
sudo apt install -y git        # Ubuntu
# OR
sudo yum install -y git        # Amazon Linux

# Verify installations
node -v
npm -v
git --version

πŸ“Œ Phase 2 β€” Clone Your Project

# Navigate to home directory
cd ~

# Clone your GitHub repository
git clone https://github.com/<your-username>/<your-repo>.git

# Verify it cloned successfully
ls

# Enter the project folder
cd <your-repo>/
ls

πŸ“Œ Phase 3 β€” Backend Setup

# Navigate to backend folder
cd <your-backend-folder>/

# Check folder contents
ls

# Install backend dependencies
npm install

# Set up environment variables
cp .env.example .env          # Copy the example file
nano .env                     # Edit and fill in your actual values

Your .env file should contain:

PORT=5000
MONGODB_URI=mongodb+srv://<user>:<pass>@cluster0.xxxxx.mongodb.net/ecommercedb
JWT_SECRET=your_super_secret_jwt_key_here
NODE_ENV=production
# (Optional) Import seed / sample data
npm run data:import

# Test that the backend starts correctly
npm start
# βœ… You should see: "Server running on port 5000"
# βœ… You should see: "MongoDB Atlas Connected"
# Press Ctrl+C to stop β€” we'll use PM2 next

πŸ“Œ Phase 4 β€” Run Backend with PM2

# Install PM2 globally
sudo npm install -g pm2

# Navigate to folder containing server.js
cd <your-backend-folder>/

# Start the backend with PM2
pm2 start server.js --name backend

# Save the PM2 process list
pm2 save

# Generate PM2 startup script (auto-restart on server reboot)
pm2 startup

# ⚠️ PM2 will print a command β€” copy and run it. It looks like:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 \
startup systemd -u ubuntu --hp /home/ubuntu

# Save again after running the startup command
pm2 save

# Verify the backend is running
pm2 list
pm2 logs

Expected pm2 list output:

β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”
β”‚ id  β”‚ name     β”‚ mode    β”‚ β†Ί     β”‚ status   β”‚ cpu  β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€
β”‚ 0   β”‚ backend  β”‚ fork    β”‚ 0     β”‚ online   β”‚ 0%   β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”˜

πŸ“Œ Phase 5 β€” Frontend Build

# Navigate to frontend folder
cd ~/<your-repo>/<your-frontend-folder>/

# Install frontend dependencies
npm install

# Build for production
npm run build

# Verify build output folder was created
ls
# βœ… You should see a /build or /dist folder

Note: React apps output to /build, while Vite apps output to /dist. Check which one your project uses.


πŸ“Œ Phase 6 β€” Install & Configure Nginx

Install Nginx

# Ubuntu / Debian
sudo apt install nginx -y

# Amazon Linux
sudo yum install nginx -y

# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx        # Auto-start on every reboot

# Check Nginx is active
sudo systemctl status nginx

Configure Nginx

# Open the default config file
sudo nano /etc/nginx/sites-available/default

Replace the contents with:

server {
    listen 80;
    server_name <YOUR-EC2-PUBLIC-IP>;

    # βœ… Serve React frontend
    # Use /build for Create React App or /dist for Vite
    root /home/ubuntu/<your-repo>/<your-frontend-folder>/dist;
    index index.html;

    # βœ… Handle React Router (SPA fallback)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # βœ… Proxy all /api requests to Express backend
    location /api/ {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_cache_bypass $http_upgrade;
    }
}
# Save and exit: Ctrl+X β†’ Y β†’ Enter

# βœ… Test Nginx configuration for syntax errors
sudo nginx -t

# Expected output:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# Restart Nginx to apply the new configuration
sudo systemctl restart nginx

πŸ“Œ Phase 7 β€” Verify Everything Works

# βœ… Check PM2 backend status
pm2 list
pm2 logs

# βœ… Check Nginx status
sudo systemctl status nginx

# βœ… Check Nginx error logs (if something looks wrong)
sudo tail -f /var/log/nginx/error.log

# βœ… Check Nginx access logs
sudo tail -f /var/log/nginx/access.log

πŸ“Œ Phase 8 β€” Access Your App

Once everything is running, open a browser and visit:

http://<YOUR-EC2-PUBLIC-IP>          β†’  React Frontend
http://<YOUR-EC2-PUBLIC-IP>/api/     β†’  Express Backend API

πŸ’‘ To use a domain name instead of an IP, point your domain's DNS A record to your EC2 Public IP and update server_name in your Nginx config.


πŸ”„ Updating Your App Remotely

When you push new code changes, follow these steps to redeploy:

# 1. SSH into your EC2 instance
ssh -i your-key.pem ubuntu@<EC2-IP>

# 2. Navigate to project folder
cd ~/<your-repo>/

# 3. Pull the latest code
git pull origin main

# 4. Update backend dependencies (if package.json changed)
cd <your-backend-folder>/
npm install

# 5. Restart backend with PM2
pm2 restart backend

# 6. Rebuild the React frontend
cd ~/<your-repo>/<your-frontend-folder>/
npm install
npm run build

# 7. Restart Nginx
sudo systemctl restart nginx

# 8. Confirm everything is live
pm2 list
sudo systemctl status nginx

⚠️ Common Mistakes to Avoid

❌ Mistake βœ… Fix
Forgetting to fill in .env Always run cp .env.example .env and edit every value
Wrong build folder path in Nginx Check if your output folder is /build (CRA) or /dist (Vite)
Port 5000 not accessible Add Custom TCP 5000 inbound rule in EC2 Security Group
PM2 not surviving reboot Always run pm2 startup + pm2 save after starting
Nginx config syntax error Always run sudo nginx -t before restarting Nginx
Running npm start directly Use PM2 β€” npm start blocks terminal and stops on exit
MongoDB IP not whitelisted In Atlas: Network Access β†’ Add 0.0.0.0/0
Frontend calling wrong API URL Set REACT_APP_API_URL in frontend .env correctly
Cloning into wrong directory Always clone into home directory ~ then cd into it

πŸ“‹ Quick Reference Cheat Sheet

Task Command
SSH into EC2 ssh -i key.pem ubuntu@<EC2-IP>
Check logged-in user whoami
Update system apt update -y
Clone repository git clone <github-url>
Pull latest code git pull origin main
Install packages npm install
Seed database npm run data:import
Build frontend npm run build
Start app with PM2 pm2 start server.js --name backend
Restart PM2 app pm2 restart backend
View PM2 process list pm2 list
View PM2 logs pm2 logs
Stop PM2 app pm2 stop backend
Set PM2 auto-start pm2 startup then pm2 save
Test Nginx config sudo nginx -t
Restart Nginx sudo systemctl restart nginx
Check Nginx status sudo systemctl status nginx
View Nginx error log sudo tail -f /var/log/nginx/error.log
Edit Nginx config sudo nano /etc/nginx/sites-available/default

πŸ“ Project Structure

your-repo/
β”œβ”€β”€ your-backend-folder/
β”‚   β”œβ”€β”€ server.js            ← PM2 starts this
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ .env                 ← Fill this in on EC2
β”‚   β”œβ”€β”€ .env.example         ← Template for .env
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   └── db.js            ← MongoDB Atlas connection
β”‚   β”œβ”€β”€ models/
β”‚   β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ middleware/
β”‚   └── seed.js / data/      ← Sample data importer
β”‚
└── your-frontend-folder/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ src/
    └── dist/ or build/      ← Nginx serves this folder

πŸ” Default Credentials (After Seeding)

Admin:   admin@shop.com   /  Admin@1234
User:    user@shop.com    /  User@1234

⚠️ Change these immediately after your first login in production!


πŸ“ž Troubleshooting

Backend not starting?

pm2 logs          # Check for errors
node server.js    # Run directly to see full error output

Frontend showing blank page?

# Check Nginx root path is correct
sudo nano /etc/nginx/sites-available/default
# Verify the /dist or /build folder actually exists
ls ~/<your-repo>/<your-frontend-folder>/

MongoDB connection refused?

# Check .env has correct MONGODB_URI
cat .env
# Check MongoDB Atlas Network Access allows 0.0.0.0/0

Nginx showing 502 Bad Gateway?

# Backend is not running β€” check PM2
pm2 list
pm2 restart backend

πŸ‘€ Author

Deployed on AWS EC2 using MongoDB Atlas, PM2, and Nginx.


πŸ“„ License

This project is licensed under the MIT License.

About

Contains all the projects made to deploy on AWS using mongoAtlas

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors