Remote OpenClaw Blog
OpenClaw Reverse Proxy: Nginx and Caddy Setup Guide
What changed
This post was reviewed and updated to reflect current deployment, security hardening, and operations guidance.
What should operators know about OpenClaw Reverse Proxy: Nginx and Caddy Setup Guide?
Answer: By default, OpenClaw runs on port 18789 and serves unencrypted HTTP traffic. For local development or testing, this is fine. For a production deployment — especially one accessible from the internet — you need a reverse proxy for several important reasons. This guide covers practical deployment decisions, security controls, and operations steps to run OpenClaw, ClawDBot, or MOLTBot.
Set up a reverse proxy for OpenClaw with Nginx or Caddy. Custom domain, automatic SSL with Let's Encrypt, hide port 18789, security headers, and DNS configuration.
Marketplace
Free skills and AI personas for OpenClaw — deploy a pre-built agent in 15 minutes.
Browse the Marketplace →Join the Community
Join 500+ OpenClaw operators sharing deployment guides, security configs, and workflow automations.
Why Use a Reverse Proxy?
By default, OpenClaw runs on port 18789 and serves unencrypted HTTP traffic. For local development or testing, this is fine. For a production deployment — especially one accessible from the internet — you need a reverse proxy for several important reasons.
Custom domain. Instead of accessing your agent at http://123.45.67.89:18789, you can use https://agent.yourdomain.com. This is easier to remember, looks more professional, and is required for many integrations that expect a proper URL.
SSL/HTTPS encryption. Without encryption, anyone between your browser and your server can see your OpenClaw traffic — including conversation content, API keys in transit, and dashboard credentials. HTTPS encrypts all traffic end-to-end. Both Nginx and Caddy support automatic free SSL certificates from Let's Encrypt.
Hide the application port. Exposing port 18789 directly to the internet reveals that you are running OpenClaw and makes port scanning trivial. A reverse proxy handles traffic on standard ports 80 (HTTP) and 443 (HTTPS) and proxies it internally to OpenClaw. The application port never needs to be exposed publicly.
Security headers. A reverse proxy can add security headers (Content-Security-Policy, X-Frame-Options, HSTS, etc.) that protect against common web attacks like clickjacking, XSS, and protocol downgrade attacks.
Rate limiting and access control. You can configure the reverse proxy to limit requests per IP, block suspicious traffic, or restrict access to specific IP ranges — adding a security layer before traffic reaches OpenClaw.
DNS Setup
Before configuring your reverse proxy, set up DNS to point your domain to your server.
Step 1: Choose a subdomain. Common choices: agent.yourdomain.com, claw.yourdomain.com, ai.yourdomain.com, or openclaw.yourdomain.com.
Step 2: Create a DNS A record. In your domain registrar's DNS settings (Cloudflare, Namecheap, GoDaddy, etc.), create an A record:
| Type | Name | Value | TTL |
|---|---|---|---|
| A | agent | YOUR_SERVER_IP | 300 |
Replace YOUR_SERVER_IP with your server's public IP address. Set TTL to 300 (5 minutes) initially for faster propagation. You can increase it later.
Step 3: Verify DNS propagation. Wait a few minutes and verify:
dig agent.yourdomain.com +short
# Should return your server's IP address
If using Cloudflare: Set the proxy status to "DNS only" (grey cloud) initially. Once your reverse proxy and SSL are working, you can optionally enable Cloudflare's proxy (orange cloud) for additional CDN and DDoS protection.
Option 1: Caddy Setup
Caddy is the simplest reverse proxy available. It handles SSL certificates automatically — you literally just specify your domain name and Caddy does everything else.
Install Caddy:
# Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Configure Caddy:
sudo nano /etc/caddy/Caddyfile
Replace the contents with:
agent.yourdomain.com {
reverse_proxy localhost:18789
}
That is the entire configuration. Two lines. Caddy automatically obtains an SSL certificate from Let's Encrypt, redirects HTTP to HTTPS, and enables HTTP/2.
Start Caddy:
sudo systemctl restart caddy
sudo systemctl enable caddy
Visit https://agent.yourdomain.com in your browser. You should see the OpenClaw dashboard with a valid SSL certificate.
Enhanced Caddy configuration with security headers:
agent.yourdomain.com {
reverse_proxy localhost:18789
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
-Server
}
log {
output file /var/log/caddy/openclaw.log
format json
}
}
Option 2: Nginx Setup
Nginx is the industry standard reverse proxy. It requires more configuration than Caddy but offers maximum control and extensive documentation.
Install Nginx and Certbot:
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
Create the Nginx configuration:
sudo nano /etc/nginx/sites-available/openclaw
Add this configuration:
server {
listen 80;
server_name agent.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:18789;
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 86400;
}
}
Enable the site and test:
# Enable the site
sudo ln -s /etc/nginx/sites-available/openclaw /etc/nginx/sites-enabled/
# Test the configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
Obtain SSL certificate with Certbot:
sudo certbot --nginx -d agent.yourdomain.com
Certbot automatically modifies your Nginx configuration to add SSL, sets up certificate auto-renewal, and redirects HTTP to HTTPS. Follow the prompts to complete the process.
Verify auto-renewal:
sudo certbot renew --dry-run
Docker Compose with Reverse Proxy
You can run the reverse proxy alongside OpenClaw in a single Docker Compose stack. This keeps everything containerized and manageable.
Caddy in Docker Compose:
version: '3.8'
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
expose:
- "18789" # Only expose internally, not to host
volumes:
- ./data:/app/data
- ./config:/app/config
env_file:
- .env
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Create the Caddyfile:
agent.yourdomain.com {
reverse_proxy openclaw:18789
}
Notice that in Docker Compose, the reverse proxy connects to openclaw:18789 (the service name) instead of localhost:18789. Docker's internal networking handles the routing.
Also notice that the openclaw service uses expose instead of ports — this means port 18789 is accessible within the Docker network but not from the host or internet. Only Caddy's ports 80 and 443 are exposed publicly.
Security Headers
Security headers protect your OpenClaw dashboard against common web attacks. Here are the recommended headers and what they do:
- Strict-Transport-Security (HSTS): Forces browsers to always use HTTPS. Prevents protocol downgrade attacks.
- X-Content-Type-Options: nosniff: Prevents browsers from guessing content types, which can lead to XSS attacks.
- X-Frame-Options: SAMEORIGIN: Prevents your dashboard from being embedded in an iframe on another site (clickjacking protection).
- Referrer-Policy: Controls how much referrer information is sent with requests. Prevents leaking internal URLs.
- Content-Security-Policy: Controls which resources the browser is allowed to load. Prevents XSS and injection attacks.
Nginx security headers:
# Add inside the server block
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header X-XSS-Protection "1; mode=block" always;
server_tokens off; # Hide Nginx version
WebSocket Support
OpenClaw uses WebSockets for real-time features like live conversation updates and Talk Mode. Your reverse proxy must support WebSocket connections.
Caddy: WebSocket support is automatic. No additional configuration needed.
Nginx: The configuration above already includes WebSocket support through these lines:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
The proxy_read_timeout 86400 (24 hours) prevents Nginx from closing idle WebSocket connections prematurely. Adjust this value if you need longer persistent connections.
Adding Basic Authentication
For an extra layer of security, add HTTP Basic Authentication so visitors must enter a username and password before even reaching the OpenClaw login page.
Caddy basic auth:
agent.yourdomain.com {
basicauth / {
admin $2a$14$... # Generate hash with: caddy hash-password
}
reverse_proxy localhost:18789
}
Generate the password hash:
caddy hash-password
# Enter your desired password when prompted
# Copy the output hash into the Caddyfile
Nginx basic auth:
# Create a password file
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admin
# Enter password when prompted
# Add to the Nginx server block:
# auth_basic "OpenClaw";
# auth_basic_user_file /etc/nginx/.htpasswd;
Basic auth adds a browser-level password prompt before any OpenClaw content is served. This is useful for public-facing instances where you want to prevent unauthorized access to the dashboard entirely.
Troubleshooting
SSL certificate not issuing. Let's Encrypt needs to reach your server on port 80 to verify domain ownership. Check that port 80 is open in your firewall (sudo ufw allow 80), your DNS A record points to the correct IP, and no other service is using port 80.
502 Bad Gateway. This means the reverse proxy cannot connect to OpenClaw. Verify OpenClaw is running (docker compose ps or systemctl status openclaw). Check that it is listening on the expected port (curl http://localhost:18789). If using Docker Compose, verify both services are on the same Docker network.
WebSocket connections failing. Symptoms: the dashboard loads but real-time updates don't work, or Talk Mode fails. Verify your Nginx config includes the WebSocket headers (Upgrade, Connection). Check for intermediary proxies or CDNs (like Cloudflare) that may need WebSocket support enabled.
Mixed content warnings. If you see browser warnings about mixed HTTP/HTTPS content, ensure OpenClaw knows it is behind an HTTPS proxy. Add OPENCLAW_BASE_URL=https://agent.yourdomain.com to your .env file.
Certificate renewal fails. Certbot auto-renewal runs via a systemd timer or cron job. Check its status with sudo systemctl status certbot.timer. Common failure causes: port 80 blocked by another service during renewal, DNS records changed, or the server's IP changed without updating DNS.
Slow performance through proxy. Ensure your reverse proxy is not doing unnecessary content buffering. For Nginx, add proxy_buffering off; to the location block if you experience latency. For Caddy, this is handled automatically.
