Reverse Proxy
A reverse proxy sits between clients and backend servers, forwarding requests:
Client → NGINX (Reverse Proxy) → Backend Server(s)
Why Use a Reverse Proxy?
- Security — Hide backend server details
- SSL termination — Handle encryption at one point
- Caching — Reduce backend load
- Load balancing — Distribute traffic
Basic Reverse Proxy Config
server {
listen 80;
server_name app.nextgenplayground.org;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Important Proxy Headers
| Header | Purpose |
|---|---|
Host | Original hostname requested |
X-Real-IP | Client's actual IP address |
X-Forwarded-For | Chain of proxy IPs |
X-Forwarded-Proto | Original protocol (http/https) |
Load Balancing
Distribute traffic across multiple backend servers:
Round Robin (Default)
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
server {
listen 80;
server_name app.nextgenplayground.org;
location / {
proxy_pass http://backend;
}
}Least Connections
Send to the server with fewest active connections:
upstream backend {
least_conn;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}IP Hash (Session Persistence)
Same client always goes to same server:
upstream backend {
ip_hash;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}Weighted Load Balancing
Send more traffic to powerful servers:
upstream backend {
server 192.168.1.10:3000 weight=5; # Gets 5x traffic
server 192.168.1.11:3000 weight=3; # Gets 3x traffic
server 192.168.1.12:3000 weight=1; # Gets 1x traffic
}Health Checks
NGINX automatically detects failed backends:
upstream backend {
server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.11:3000 max_fails=3 fail_timeout=30s;
server 192.168.1.12:3000 backup; # Only used if others fail
}SSL/TLS with Let's Encrypt
Install Certbot
sudo apt install certbot python3-certbot-nginx -yObtain Certificate
sudo certbot --nginx -d app.nextgenplayground.orgCertbot will:
- Verify domain ownership
- Generate SSL certificate
- Automatically update NGINX config
- Set up auto-renewal
Resulting Config
Certbot modifies your server block:
server {
listen 443 ssl;
server_name app.nextgenplayground.org;
ssl_certificate /etc/letsencrypt/live/app.nextgenplayground.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.nextgenplayground.org/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://backend;
}
}
# HTTP to HTTPS redirect
server {
listen 80;
server_name app.nextgenplayground.org;
return 301 https://$host$request_uri;
}Auto-Renewal
Certbot sets up automatic renewal. Verify:
# Test renewal
sudo certbot renew --dry-run
# Check timer
sudo systemctl status certbot.timerComplete Production Example
upstream app_servers {
least_conn;
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 backup;
}
server {
listen 80;
server_name app.nextgenplayground.org;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name app.nextgenplayground.org;
ssl_certificate /etc/letsencrypt/live/app.nextgenplayground.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.nextgenplayground.org/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
# Proxy to backend
location / {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# Static assets (served directly by NGINX)
location /static/ {
alias /var/www/app/static/;
expires 30d;
access_log off;
}
# Health check endpoint
location /health {
access_log off;
return 200 "OK\n";
}
}Summary
- Reverse proxy forwards client requests to backend servers
- Always set
proxy_set_headerfor proper IP forwarding - Load balancing algorithms: round-robin, least_conn, ip_hash, weighted
max_failsandfail_timeouthandle backend failures- Let's Encrypt provides free SSL certificates via Certbot
- Always redirect HTTP → HTTPS in production
- Use
backupservers for failover
Next Steps
Next, we'll set up MariaDB — the database server used in production LEMP stacks.