← ~/content

OpenClaw Part 6: HTTPS & Clean URLs with Caddy

Tutorial~6 min read
OpenClaw Part 6: HTTPS & Clean URLs with Caddy
intermediate~20 min

Prerequisites

  • Completed Parts 1-5
  • Existing Caddy reverse proxy with Cloudflare DNS
  • Existing Pi-hole DNS server

Tools

  • SSH terminal
  • Web browser

Software

  • caddy2.11.1
  • pihole6.4
Watch on YouTube

After Parts 1-5, the setup works but has rough edges. Element Web throws "browser not supported" warnings over HTTP. Service workers won't load, so avatars and uploaded images don't display. Credentials are sent unencrypted on the LAN. And you need an SSH tunnel just to access WebChat.

This is a short one. Three DNS records, three Caddy entries, a few config updates. Takes the setup from "it works on my LAN" to "I'd actually leave this running."

NOTE

This is Part 6 (bonus) of a 6-part series. Everything functional was built in Parts 1-5. This part is polish — HTTPS, proper URLs, no browser warnings, no SSH tunnels.

Prerequisites

  • Completed Parts 1-5 (full pipeline working)
  • A Caddy reverse proxy with automatic HTTPS (we use Cloudflare DNS challenge for Let's Encrypt certs)
  • A Pi-hole DNS server (or any local DNS you manage)
  • Caddy and Pi-hole need to be able to reach VLAN 20 (Matrix container) and the OpenClaw machine

What This Fixes

  • Element Web "browser not supported" warning — gone
  • Service worker errors — gone (media loads properly)
  • Plain HTTP credentials — encrypted via HTTPS
  • Raw IP URLs (http://10.1.20.152) — proper subdomains (https://element.hake.rodeo)
  • SSH tunnel required for WebChat — gone (https://claw.hake.rodeo)

Step 1: Add Pi-hole DNS Records

All three domains point to Caddy's IP. Caddy handles HTTPS termination and proxies to the actual services.

In Pi-hole's admin UI (or via the REST API):

  • matrix.hake.rodeo -> your Caddy IP (e.g., 10.1.10.101)
  • element.hake.rodeo -> your Caddy IP (e.g., 10.1.10.101)
  • claw.hake.rodeo -> your Caddy IP (e.g., 10.1.10.101)

Pi-hole admin interface showing local DNS records with matrix.hake.rodeo pointing to 10.1.10.101 being added

NOTE

Replace hake.rodeo with your own domain, and the Caddy IP with wherever your reverse proxy lives.

Verify all three resolve:

On any machine using Pi-hole DNS
dig +short matrix.hake.rodeo @YOUR_PIHOLE_IP
On any machine using Pi-hole DNS
dig +short element.hake.rodeo @YOUR_PIHOLE_IP
On any machine using Pi-hole DNS
dig +short claw.hake.rodeo @YOUR_PIHOLE_IP

Terminal showing dig +short commands verifying matrix.hake.rodeo, element.hake.rodeo, and claw.hake.rodeo all resolve to 10.1.10.101

All three should resolve to your Caddy IP.

Step 2: Add Caddy Reverse Proxy Entries

Open the Caddyfile:

On Caddy host
nano /etc/caddy/Caddyfile

Add the following three entries:

Caddyfile entries to add
# Matrix homeserver (Continuwuity)
matrix.hake.rodeo {
    reverse_proxy 10.1.20.152:8008
}
 
# Element Web Matrix client
element.hake.rodeo {
    reverse_proxy 10.1.20.152:80
}
 
# OpenClaw Gateway (WebChat + Control UI)
claw.hake.rodeo {
    reverse_proxy YOUR_OPENCLAW_IP:18789
}

Caddy handles WebSocket proxying automatically — no extra config needed for OpenClaw's WebChat connection.

NOTE

If your Caddy uses a global acme_dns block for Cloudflare DNS challenge (like ours does), you don't need per-site TLS config. Caddy handles certificates automatically.

Reload Caddy:

On Caddy host
sudo systemctl reload caddy

WARNING

Don't use caddy reload from the CLI if your Cloudflare API token is in the systemd environment. The CLI doesn't have access to systemd env vars and will fail with "API token appears invalid." Use systemctl reload caddy instead.

Verify all three endpoints:

On any machine
curl -sk https://matrix.hake.rodeo/_matrix/client/versions | head -1
On any machine
curl -sk https://element.hake.rodeo | head -5
On any machine
curl -sk https://claw.hake.rodeo | head -5

Step 3: Update OpenClaw Gateway Config

Add the new HTTPS URL to the allowed origins so WebChat works through the reverse proxy:

On OpenClaw machine
openclaw config set gateway.controlUi.allowedOrigins '["http://localhost:18789","http://127.0.0.1:18789","https://claw.hake.rodeo"]'

NOTE

Keep the localhost entries — they're needed if you ever access the UI directly. The new HTTPS entry tells the gateway to accept WebSocket connections from the Caddy-proxied URL.

Step 4: Update OpenClaw's Matrix Config

Update the homeserver URL so OpenClaw connects to Matrix over HTTPS:

On OpenClaw machine
openclaw config set channels.matrix.homeserver "https://matrix.hake.rodeo"

Now restart the gateway to apply both config changes:

On OpenClaw machine
systemctl --user restart openclaw-gateway

Step 5: Update Continuwuity Well-Known

Tell Matrix clients to use the HTTPS URL. Open the config on your Matrix container:

On Matrix container
nano /etc/conduwuit/conduwuit.toml

Find the [global.well_known] section and update it:

/etc/conduwuit/conduwuit.toml (well_known section)
[global.well_known]
client = "https://matrix.hake.rodeo"
server = "matrix.hake.rodeo:443"

Restart Continuwuity:

On Matrix container
systemctl restart conduwuit

NOTE

The server_name stays unchanged. We're only updating where clients connect — not the identity.

Step 6: Update Element Web Config

Open the Element Web config:

On Matrix container
nano /var/www/element-web/config.json

Update the base_url to use HTTPS:

/var/www/element-web/config.json
{
    "default_server_config": {
        "m.homeserver": {
            "base_url": "https://matrix.hake.rodeo"
        }
    },
    "disable_custom_urls": false,
    "disable_guests": true,
    "disable_3pid_login": true,
    "brand": "Element",
    "default_theme": "dark",
    "default_federate": false,
    "room_directory": {
        "servers": []
    }
}

No service restart needed — it's a static file served by nginx.

Step 7: Test Everything

Element Web

Open https://element.hake.rodeo in your browser.

  • The "browser not supported" warning should be gone
  • The "service worker failed" warning should be gone
  • Profile pictures and media should load
  • The padlock icon shows a valid Let's Encrypt certificate

Log in and verify the bot is connected.

OpenClaw WebChat

Open https://claw.hake.rodeo in your browser. You'll be prompted for the gateway token — enter it to authenticate.

After entering the token, WebChat will show "pairing required." This is the device approval flow. On the OpenClaw machine, check for the pending request:

On OpenClaw machine
openclaw devices list

Terminal showing openclaw devices list with a pending device pairing request showing request ID, device ID, operator role, and scopes

You should see a pending request from the new WebChat connection. Approve it using the request ID:

On OpenClaw machine
openclaw devices approve REQUEST_ID

Terminal showing openclaw devices approve command with successful approval of a pending device pairing request

Refresh the WebChat page — it should connect. Chat with the agent to confirm it's working.

No more ssh -L 18789:localhost:18789 — just a clean URL.

Full Pipeline

Trigger a failure to test the complete pipeline over HTTPS:

On Proxmox host
pct exec 150 -- systemctl stop nginx

The investigation report should land in Matrix through the HTTPS connection. After verifying:

On Proxmox host
pct exec 150 -- systemctl start nginx

Series Complete

Six parts, one AI monitoring pipeline:

  1. Part 1 — OpenClaw + Ollama on Strix Halo
  2. Part 2 — Diagnostic scripts + Uptime Kuma incident response
  3. Part 3 — Matrix integration for a proper command center
  4. Part 4 — Local model shootout (6 models compared)
  5. Part 5 — Backup, restore, and maintenance
  6. Part 6 — HTTPS & clean URLs with Caddy

From a fresh Ubuntu Server to a fully self-hosted AI monitoring system with automated incident investigation, Matrix reporting, tested backups, and HTTPS. Running entirely on local hardware with no cloud dependencies.

Related Products

Some links are affiliate links. I may earn a small commission at no extra cost to you.