Skip to main content
In development, the OpenClaw gateway listens on localhost:18789 and the website connects to it directly. In production, you need HTTPS and proper domain names. This guide sets up Caddy as a reverse proxy with automatic SSL certificates.

Architecture

Both domains proxy to the same OpenClaw gateway on localhost:18789. The gateway serves the LogLife plugin API (/loglife/*) and the OpenClaw Control UI (/__openclaw__/) on the same port. Caddy handles SSL, domain routing, and access control.

Why a reverse proxy?

  • HTTPS: Without it, API keys and gateway tokens travel in plain text. Caddy gets free SSL certificates from Let’s Encrypt automatically.
  • Access control: The API domain is open (protected by Bearer token). The admin domain adds HTTP basic auth so the Control UI is not publicly accessible.
  • Clean URLs: Users and Vercel connect to https://api.loglife.co instead of http://123.45.67.89:18789.
  • Port isolation: Port 18789 stays closed to the public. Only Caddy reaches it internally.

DNS setup

Add two A records in your DNS provider (e.g. GoDaddy, Cloudflare) pointing to your server’s IP: Both records point to the same IP. Caddy differentiates them by domain name.
DNS changes can take up to an hour to propagate, but typically complete in under 5 minutes.

Caddy setup

Install Caddy

Generate a password hash

Pick a username and password for the Control UI. Caddy uses bcrypt hashes:
Copy the output (starts with $2a$14$...).

Configure Caddy

Edit /etc/caddy/Caddyfile:
Replace admin with your chosen username and paste the hash from the previous step.

Gateway token

The Control UI has its own authentication layer (separate from Caddy’s basic auth). After passing basic auth, the Control UI will prompt for the gateway token. The gateway auto-generates this token on first startup and saves it to ~/.openclaw/openclaw.json. Read it with:
If you need to regenerate it (e.g. after a suspected leak):
The gateway token, the Caddy basic auth password, and the LogLife API key are three separate credentials:
  • Gateway token (gateway.auth.token) — authenticates the Control UI and CLI connections to the gateway
  • Caddy basic auth — protects admin.loglife.co from public access
  • LogLife API key (plugins.entries.loglife.config.apiKey) — authenticates Vercel’s requests to the plugin endpoints

Start Caddy

Caddy automatically obtains SSL certificates. No additional configuration needed.

Firewall

Open ports 80 and 443, and close direct access to the gateway port:
Hetzner Cloud users: Hetzner has its own firewall layer that runs above ufw. Even if ufw allows a port, Hetzner’s firewall can still block it. Go to the Hetzner Cloud Console > your project > Firewalls and add inbound rules for TCP 80 and TCP 443 from 0.0.0.0/0 and ::/0. Without this, Caddy cannot complete the ACME challenge and SSL certificates will fail with “Timeout during connect (likely firewall problem)”.
Other cloud providers (AWS, GCP, DigitalOcean, etc.) have similar external firewalls — security groups, VPC firewall rules, or cloud firewalls. Always check both the OS-level firewall (ufw, iptables) and the cloud provider’s firewall when ports appear closed.

Verify

Update Vercel

After Caddy is running, update the OPENCLAW_API_URL in your Vercel project settings: The OPENCLAW_API_KEY stays the same.

Troubleshooting

DNS

Check your DNS records:
Both should return your server’s IP. If not, verify the A records in your DNS provider (GoDaddy, Cloudflare, etc.). DNS changes can take up to an hour to propagate — wait and retry.
DNS is fine, but the server isn’t accepting connections. Check that Caddy is running and ports are open:
If nothing is listening on 80/443, restart Caddy: sudo systemctl restart caddy.

SSL certificates

This means Let’s Encrypt cannot reach your server on port 80 or 443 to verify domain ownership. Most common causes:
  1. Cloud provider firewall (Hetzner, AWS, GCP, etc.) is blocking inbound traffic — see the warning above about Hetzner Cloud Firewalls.
  2. OS firewall (ufw or iptables) is blocking port 80. Check with sudo ufw status or sudo iptables -L -n.
  3. Another service is already using port 80 (e.g. Apache). Check with sudo ss -tlnp | grep :80.
After fixing the firewall, restart Caddy so it retries:
Look for “certificate obtained successfully” in the logs.
If curl https://api.loglife.co fails with an SSL error from the server, it may be because the certificate hasn’t been issued yet. Check Caddy logs:
If certificates are still being obtained, wait a moment and retry. Caddy will retry automatically on failure.

Reverse proxy

The OpenClaw gateway is not running. Start it:
Verify it’s listening:
The Bearer token doesn’t match. Check that the key in Vercel matches the key in OpenClaw’s config:
Update whichever side is out of sync. If you regenerated the key, update both Vercel and GitHub secrets.
The OpenClaw gateway may also require its own authentication token. You’ll see the basic auth prompt from Caddy first, then the gateway may require its own credentials. Check your gateway config:
The gateway token is separate from the Caddy basic auth password and from the LogLife API key.
The issue is between Vercel’s servers and your server. Check step by step:
If step 2 times out, ports 80/443 are blocked at the cloud provider level. If step 3 returns 401, the API key is wrong.