Running OpenClaw behind a reverse proxy gives you HTTPS, custom domains, and the ability to run multiple services on one server. Here's how to set it up correctly with Caddy, Nginx, or Traefik.
Why Use a Reverse Proxy?
- HTTPS with auto-TLS: Free SSL certificates via Let's Encrypt
- Custom domain: Access OpenClaw at
openclaw.yourdomain.com - Security: Hide the gateway port from the public internet
- Multi-service: Run OpenClaw alongside other apps on the same server
The Trusted Proxies Setting
This is the most important step. Without it, OpenClaw can't tell the difference between a real local connection and a spoofed one.
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
If you skip this, you'll see:
WARN gateway.trusted_proxies_missing
Reverse proxy headers are not trusted.
And OpenClaw's local-client checks won't work properly through the proxy.
What trustedProxies Does
When a request comes through a reverse proxy, the original client IP is lost. The proxy adds it back via X-Forwarded-For headers. But OpenClaw only trusts these headers from IPs in the trustedProxies list.
Without it:
- OpenClaw sees all requests as coming from
127.0.0.1(the proxy) - It can't enforce per-client access controls
- The security audit will flag
trusted_proxies_missing
Caddy Setup
Caddy is the easiest option — automatic HTTPS, minimal config.
Caddyfile
openclaw.yourdomain.com {
reverse_proxy localhost:3001
}
That's it. Caddy automatically:
- Obtains a Let's Encrypt certificate
- Handles HTTPS termination
- Forwards requests to OpenClaw
OpenClaw Config for Caddy
openclaw config set gateway.mode local
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
openclaw restart
Reload Caddy
caddy reload --adapter caddyfile --config /etc/caddy/Caddyfile
Important: Always include --adapter caddyfile when reloading. Without it, Caddy may fail silently.
Nginx Setup
Nginx Config
server {
listen 443 ssl;
server_name openclaw.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/openclaw.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/openclaw.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3001;
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;
}
}
server {
listen 80;
server_name openclaw.yourdomain.com;
return 301 https://$server_name$request_uri;
}
Key points:
- WebSocket support: The
UpgradeandConnectionheaders are required for OpenClaw's real-time connection - Forwarded headers:
X-Real-IPandX-Forwarded-Forpass the real client IP to OpenClaw - HTTPS redirect: Force all traffic to HTTPS
Get SSL Certificate (Certbot)
sudo certbot --nginx -d openclaw.yourdomain.com
OpenClaw Config for Nginx
openclaw config set gateway.mode local
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
openclaw restart
Traefik Setup
docker-compose.yml
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.le.acme.email=you@example.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "letsencrypt:/letsencrypt"
openclaw:
image: openclaw-stack
labels:
- "traefik.http.routers.openclaw.rule=Host(`openclaw.yourdomain.com`)"
- "traefik.http.routers.openclaw.tls.certresolver=le"
- "traefik.http.services.openclaw.loadbalancer.server.port=3001"
environment:
- OPENCLAW_GATEWAY_TOKEN=your-stable-token
DNS Configuration
Point your domain to your server's IP:
Type: A
Name: openclaw (or subdomain of choice)
Value: YOUR_SERVER_IP
TTL: 300
Cloudflare users: If using Cloudflare's free plan with a wildcard subdomain, set the DNS record to DNS only (grey cloud), not Proxied (orange cloud). Cloudflare's free plan doesn't support proxied wildcard DNS records.
Security Audit
After setting up the proxy, run OpenClaw's security audit:
openclaw security audit
You should see:
OK gateway.trusted_proxies — reverse proxy headers are trusted
For a deeper analysis:
openclaw security audit --deep
This checks:
- Trusted proxy configuration
- Attack surface (open ports, enabled tools)
- Webhook security
- Browser control settings
Troubleshooting
"trusted_proxies_missing" Warning
openclaw config set gateway.trustedProxies '["127.0.0.1"]'
openclaw restart
Dashboard Loads But Can't Connect
WebSocket connections need special proxy config. Make sure your proxy passes Upgrade and Connection headers.
Certificate Errors
- DNS must point to your server before requesting a cert
- Port 80 must be open for HTTP-01 challenge (Let's Encrypt)
- Cloudflare proxy must be disabled during initial cert issuance
502 Bad Gateway
OpenClaw isn't running or isn't on the expected port:
openclaw status
openclaw config get gateway.port
Pre-Configured Proxy
ClawTank handles reverse proxy, TLS certificates, and subdomain routing automatically. Each instance gets its own HTTPS subdomain — no proxy configuration needed.
