Reverse Proxy
Put the 3x-ui panel and subscription behind Nginx or Caddy with Let's Encrypt TLS.
A reverse proxy lets you serve the panel and subscription on a clean domain with
automatic HTTPS, and hide the real ports behind ports 80/443. Prefer to let the
panel terminate TLS directly? Get a certificate with the
x-ui SSL menu instead.
Generate a config
Reverse-proxy config generator
Generate an Nginx or Caddy reverse-proxy config (with WebSocket support) and a matching certificate command.
server {
listen 443 ssl http2;
server_name panel.example.com;
ssl_certificate /etc/letsencrypt/live/panel.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/panel.example.com/privkey.pem;
location /panel/ {
proxy_pass http://127.0.0.1:2053;
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_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}certbot certonly --nginx -d panel.example.comThe panel uses WebSockets for live updates, so the proxy must pass the
Upgrade/Connection headers (the Nginx output above already does). Caddy
handles WebSocket upgrades automatically.
Nginx + certificate
With Nginx, obtain a certificate with certbot (or acme.sh) and reference it
in the server block:
certbot certonly --nginx -d panel.example.comReload Nginx after installing the certificate, and set up automatic renewal
(certbot renew runs on a timer by default).
Caddy
Caddy obtains and renews certificates for you — point a Caddyfile at the panel and it just works:
panel.example.com {
reverse_proxy 127.0.0.1:2053
}Tips
- Keep the panel's web base path even behind a proxy; defense in depth.
- If you terminate TLS at the proxy, you may want
XUI_SKIP_HSTS=trueon the panel — see the environment variables reference. - Proxy the subscription server too, so its contents are served over HTTPS.

3x-ui