Configure a Reverse Proxy
This guide explains how to set up a reverse proxy with Nginx or Traefik on your VPS.
What is a Reverse Proxy?​
A reverse proxy is a server that sits in front of your applications and redirects traffic to them. Benefits:
- Single entry point for multiple applications
- Centralized SSL/HTTPS
- Different domain names for each service
- Load balancing if needed
Option 1: Nginx​
Installation​
sudo apt update
sudo apt install nginx
Basic Configuration​
Create a configuration file for your site:
sudo nano /etc/nginx/sites-available/my-app
Proxy to a Local Application​
server {
listen 80;
server_name my-app.example.com;
location / {
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_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;
}
}
Enable the Site​
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Add SSL with Let's Encrypt​
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d my-app.example.com
Multi-Application Example​
# Application 1 - api.example.com
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# Application 2 - dashboard.example.com
server {
listen 80;
server_name dashboard.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Option 2: Traefik (with Docker)​
Traefik is ideal if you use Docker because it automatically detects containers.
docker-compose.yml for Traefik​
version: '3.8'
services:
traefik:
image: traefik:v3.0
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.middlewares=auth"
- "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$xyz..."
restart: unless-stopped
# Example application
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
restart: unless-stopped
Add an Application with Traefik​
my-app:
image: my-image
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "traefik.http.routers.my-app.entrypoints=websecure"
- "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
- "traefik.http.services.my-app.loadbalancer.server.port=3000"
Nginx vs Traefik Comparison​
| Criteria | Nginx | Traefik |
|---|---|---|
| Configuration | Manual files | Docker auto-discovery |
| SSL | Separate Certbot | Built-in |
| Reload | nginx reload | Automatic |
| Web interface | No (except plugins) | Dashboard included |
| Ideal for | Traditional servers | Docker environments |
HTTP to HTTPS Redirect​
With Nginx​
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
With Traefik​
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
Tip
For Docker environments, prefer Traefik. For traditional servers, Nginx remains the reference.