🧠 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?
| Benefit | Explanation |
|---|---|
| 🔒 Security | Hide your backend ports (like 5000, 3000) from the public. |
| 🌐 Clean URLs | Access app via http://example.com instead of :5000. |
| 🔁 Load Balancing | Nginx can distribute traffic to multiple app instances. |
| ⚡ Caching | It can cache static assets to improve performance. |
| 🔄 SSL Termination | Nginx 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 nginx2️⃣ Edit the Config
sudo nano /etc/nginx/nginx.confAdd 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 nginx4️⃣ 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-nginxFor Ubuntu/Debian:
sudo apt update
sudo apt install certbot python3-certbot-nginx2️⃣ 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 --nginxIt 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.crtUpdate 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 nginxAccess 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.
✅ Option 3: Get a Domain (Recommended)
Use a free/cheap domain and Let’s Encrypt:
Add an A record → point to EC2 IP → get HTTPS for free. ✅
💡 TL;DR
| Method | HTTPS | Browser Warning | Cost | Best Use |
|---|---|---|---|---|
| Let’s Encrypt + IP | ❌ | ❌ | Free | Not possible |
| Self-Signed Cert | ✅ | ⚠️ | Free | Testing |
| Paid Cert (IP-based) | ✅ | ✅ | Expensive | Special cases |
| Domain + Let’s Encrypt | ✅ | ✅ | Free / Cheap | Recommended ✅ |