π§ 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 β |