LocalHake

Tutorial

OpenClaw Part 6: HTTPS & Clean URLs with Caddy

Harden an OpenClaw setup with HTTPS and clean hostnames. Add Pi-hole DNS records and Caddy reverse-proxy entries so every service loads securely, no warnings.

Hake HardwarePublished Updated ~20 minintermediate

This post contains paid links (affiliate) — how that works.


▶ Watch this build on YouTube
Contents

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 DNSbash
dig +short matrix.hake.rodeo @YOUR_PIHOLE_IP
On any machine using Pi-hole DNSbash
dig +short element.hake.rodeo @YOUR_PIHOLE_IP
On any machine using Pi-hole DNSbash
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 hostbash
nano /etc/caddy/Caddyfile

Add the following three entries:

Caddyfile entries to addtext
# 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 hostbash
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 machinebash
curl -sk https://matrix.hake.rodeo/_matrix/client/versions | head -1
On any machinebash
curl -sk https://element.hake.rodeo | head -5
On any machinebash
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 machinebash
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 machinebash
openclaw config set channels.matrix.homeserver "https://matrix.hake.rodeo"

Now restart the gateway to apply both config changes:

On OpenClaw machinebash
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 containerbash
nano /etc/conduwuit/conduwuit.toml

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

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

Restart Continuwuity:

On Matrix containerbash
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 containerbash
nano /var/www/element-web/config.json

Update the base_url to use HTTPS:

/var/www/element-web/config.jsonjson
{
    "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 machinebash
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 machinebash
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 hostbash
pct exec 150 -- systemctl stop nginx

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

On Proxmox hostbash
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.

Gear used