Skip to content

Set up a reverse proxy

A reverse proxy sits between clients and Quackback, handling SSL/TLS termination, compression, and security headers. Always use one in production.

Never expose port 3000 directly to the internet. Use a reverse proxy for HTTPS.

Required Headers

Your reverse proxy must pass these headers to Quackback:

HeaderPurpose
HostOriginal hostname
X-Real-IPClient IP address
X-Forwarded-ForProxy chain
X-Forwarded-ProtoProtocol (http/https)
UpgradeWebSocket support
ConnectionKeep-alive handling

Caddy

Caddy automatically provisions SSL certificates from Let's Encrypt. It is the simplest option for most deployments.

Create /etc/caddy/Caddyfile:

feedback.yourcompany.com {
    reverse_proxy localhost:3000
    encode gzip zstd
}

Start Caddy:

sudo systemctl enable caddy
sudo systemctl start caddy

That's it. Caddy handles HTTPS, certificate renewal, and compression automatically.

Nginx

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

server {
    listen 80;
    server_name feedback.yourcompany.com;
    return 301 https://$server_name$request_uri;
}
 
server {
    listen 443 ssl http2;
    server_name feedback.yourcompany.com;
 
    ssl_certificate /etc/letsencrypt/live/feedback.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/feedback.yourcompany.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
 
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
 
    gzip on;
    gzip_types text/plain text/css application/json application/javascript image/svg+xml;
 
    location / {
        proxy_pass http://127.0.0.1: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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Enable the site and obtain a certificate:

sudo ln -s /etc/nginx/sites-available/quackback /etc/nginx/sites-enabled/
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d feedback.yourcompany.com
sudo nginx -t && sudo systemctl reload nginx

Traefik

Add labels to your Quackback service in docker-compose.yml:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.quackback.rule=Host(`feedback.yourcompany.com`)"
  - "traefik.http.routers.quackback.tls.certresolver=letsencrypt"
  - "traefik.http.services.quackback.loadbalancer.server.port=3000"

See the Traefik documentation for full configuration including the certificate resolver setup.

Apache

See the Apache reverse proxy documentation for setup with mod_proxy. You need mod_proxy, mod_proxy_http, mod_proxy_wstunnel, mod_ssl, and mod_headers enabled.

Troubleshooting

502 Bad Gateway

  • Verify Quackback is running: curl http://localhost:3000
  • Check that the proxy_pass address and port match your Quackback instance

WebSocket Connection Failed

Make sure your proxy passes WebSocket upgrade headers:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Mixed Content Warnings

Ensure the X-Forwarded-Proto: https header is passed and BASE_URL in your .env uses https://.

Redirect Loops

Check that BASE_URL in .env uses https://.

Next Steps