🧠 What is a Reverse Proxy?

A reverse proxy is like a smart middleman that sits in front of your app/server, receives requests from clients (like a browser), and then forwards those requests to your backend service (like your Node.js app running on port 5000).


🔁 Without vs. With Reverse Proxy

❌ Without Reverse Proxy:
User → http://3.7.70.216:5000 → Node.js (direct on port 5000)
You have to expose port 5000, which is non-standard.

✅ With Reverse Proxy (Nginx):
User → http://3.7.70.216 → Nginx (on port 80) → Node.js (on 5000 internally)
Only port 80 (standard HTTP) is open to the public, but internally Nginx passes traffic to your Node.js app on port 5000.


🚀 Why use a Reverse Proxy?

BenefitExplanation
🔒 SecurityHide your backend ports (like 5000, 3000) from the public.
🌐 Clean URLsAccess app via http://example.com instead of :5000.
🔁 Load BalancingNginx can distribute traffic to multiple app instances.
⚡ CachingIt can cache static assets to improve performance.
🔄 SSL TerminationNginx handles HTTPS so your app can stay HTTP internally.

🛠️ How to Set Up Nginx as a Reverse Proxy for Node.js

1️⃣ Install Nginx on EC2

sudo yum install nginx -y    # For Amazon Linux
sudo systemctl start nginx
sudo systemctl enable nginx

2️⃣ Edit the Config

sudo nano /etc/nginx/nginx.conf

Add this inside the http {} block (or use a site config file):

server {
    listen 80;
    server_name _;
 
    location / {
        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_cache_bypass $http_upgrade;
    }
}

3️⃣ Restart Nginx

sudo systemctl restart nginx

4️⃣ Access Your App

Open your browser and go to:
👉 http://your-public-ip


🧪 Bonus: Add HTTPS with Let’s Encrypt

You can add SSL/TLS with Let’s Encrypt for free — so Nginx will serve secure traffic (https://) 🔒


🔐 SSL/TLS with Let’s Encrypt + Nginx

🧠 What is SSL/TLS?

  • SSL/TLS is what makes the https:// in your URL secure.
  • It encrypts data between the browser and your server, preventing eavesdropping.

Example:
http://yourdomain.com ❌ (Not secure)
https://yourdomain.com ✅ (Secure with padlock)


🛠️ What is Let’s Encrypt?

  • It’s a free, automated, and open certificate authority.
  • It provides an SSL certificate that browsers trust.
  • You can use it with Certbot, a tool that auto-generates and installs the certificate with Nginx.

✅ Requirements

1️⃣ A domain name (e.g., myapp.omdev.in)
2️⃣ DNS A record pointing to your EC2 public IP
3️⃣ Nginx installed on EC2
4️⃣ Ports 80 and 443 open in EC2 Security Group


🚀 Steps to Set Up HTTPS with Let’s Encrypt (Certbot + Nginx)

1️⃣ Install Certbot and Nginx Plugin

For Amazon Linux 2:

sudo yum install -y epel-release
sudo yum install -y certbot python2-certbot-nginx

For Ubuntu/Debian:

sudo apt update
sudo apt install certbot python3-certbot-nginx

2️⃣ Verify Nginx Config

Make sure you have a server block like this:

server {
    listen 80;
    server_name yourdomain.com;
 
    location / {
        proxy_pass http://localhost:5000;
    }
}

3️⃣ Run Certbot

sudo certbot --nginx

It will:

  • Ask for your domain name (e.g., myapp.omdev.in)
  • Generate an SSL certificate
  • Update Nginx config
  • Reload Nginx automatically ✅

4️⃣ Test HTTPS

Visit: https://yourdomain.com 🎉
You’ll see the 🔒 padlock!


🔁 Auto-Renewal

Let’s Encrypt certificates expire every 90 days, but Certbot sets up a cron job to auto-renew.

Test renewal manually:

sudo certbot renew --dry-run

🤔 What if I Don’t Have a Domain?

Let’s Encrypt won’t work with a public IP (e.g., http://3.7.70.216) — it needs a domain name.

You can buy one (e.g., Namecheap, GoDaddy) or get a free one from Freenom.


🌍 Using HTTPS Without a Domain Name

🔒 Can You Use HTTPS with Just a Public IP?

Yes, but…
Not with Let’s Encrypt


❌ Why Let’s Encrypt Doesn’t Work with IPs

  • It requires a domain for validation.
  • The HTTP-01 challenge checks DNS records — which doesn’t work for raw IPs.

✅ Option 1: Use a Self-Signed Certificate

Good for testing, but browsers will show ⚠️ “Your connection is not private”.

# Generate a private key and cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout selfsigned.key -out selfsigned.crt

Update your Nginx config:

server {
    listen 443 ssl;
    server_name 3.7.70.216;
 
    ssl_certificate /path/to/selfsigned.crt;
    ssl_certificate_key /path/to/selfsigned.key;
 
    location / {
        proxy_pass http://localhost:5000;
    }
}

Then reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Access via:
https://3.7.70.216 ⚠️ (browser warning expected)


✅ Option 2: Buy a Paid IP-Based Certificate

  • Some CAs (like DigiCert) support this.
  • Works for static, dedicated IPs only.
  • Costly — not ideal for simple setups.

Use a free/cheap domain and Let’s Encrypt:

Add an A record → point to EC2 IP → get HTTPS for free. ✅


💡 TL;DR

MethodHTTPSBrowser WarningCostBest Use
Let’s Encrypt + IPFreeNot possible
Self-Signed Cert⚠️FreeTesting
Paid Cert (IP-based)ExpensiveSpecial cases
Domain + Let’s EncryptFree / CheapRecommended ✅