What is a Reverse Proxy?
A reverse proxy sits in front of your applications and routes requests based on domain name, path, or other criteria. This lets you:
- Run multiple apps on one server with one IP
- Terminate SSL in one place
- Add caching, rate limiting, and security headers
- Load balance across multiple backends
Basic Setup
sudo apt install -y nginx
sudo systemctl enable nginx
Single App Proxy
# /etc/nginx/sites-available/myapp.conf
server {
listen 80;
server_name myapp.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
sudo ln -s /etc/nginx/sites-available/myapp.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Multiple Apps on One Server
# App 1 — Node.js on port 3000
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params;
}
}
# App 2 — Python on port 8000
server {
listen 80;
server_name app2.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
include proxy_params;
}
}
# App 3 — Go on port 8080
server {
listen 80;
server_name app3.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
include proxy_params;
}
}
WebSocket Support
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
SSL with Let's Encrypt
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d myapp.example.com
Certbot automatically modifies your Nginx config to add SSL and redirect HTTP to HTTPS.
Performance Tuning
# Enable caching for static files
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
proxy_pass http://127.0.0.1:3000;
proxy_cache_valid 200 1d;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Enable gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 256;
Tip Always include
proxy_set_header X-Real-IPandX-Forwarded-For— without these, your application sees all requests coming from 127.0.0.1.