Skip to content

Reverse Proxy

TheTerms runs on HTTP port 3000 by default. For production, place a reverse proxy in front of it to handle HTTPS termination, domain routing, and connection management.

Caddy automatically obtains and renews TLS certificates via Let’s Encrypt. It’s the simplest option.

Install Caddy on your server, then create a Caddyfile:

your-domain.com {
reverse_proxy localhost:3000
}

Start Caddy:

Terminal window
caddy run --config Caddyfile

That’s it. Caddy handles HTTPS automatically.

Install nginx and Certbot (for Let’s Encrypt certificates):

Terminal window
sudo apt install nginx certbot python3-certbot-nginx

Create /etc/nginx/sites-available/theterms:

server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost: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 and obtain a certificate:

Terminal window
sudo ln -s /etc/nginx/sites-available/theterms /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d your-domain.com

Certbot will automatically configure HTTPS and set up certificate renewal.

If you prefer a Docker-native reverse proxy, add Traefik labels to the app service in docker-compose.yml:

services:
app:
# ... existing config ...
labels:
- "traefik.enable=true"
- "traefik.http.routers.theterms.rule=Host(`your-domain.com`)"
- "traefik.http.routers.theterms.entrypoints=websecure"
- "traefik.http.routers.theterms.tls.certresolver=letsencrypt"
- "traefik.http.services.theterms.loadbalancer.server.port=3000"

Add Traefik as a service in the same docker-compose.yml:

traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "letsencrypt:/letsencrypt"
volumes:
letsencrypt: