Cloudflare tunnels — one tunnel, two replicas
homelab (e938d2cb) is the only tunnel. It has two connectors running the same ingress:
| Replica | Host | Reads | Reaches |
|---|---|---|---|
linux_amd64 | joe-host | Docker volume cloudflared-config → /etc/cloudflared/config.yml | services on 192.168.0.182; HA on 192.168.0.155 |
linux_arm64 | HA box (container cloudflared-ha) | /share/cloudflared/config.yml | the same, over the LAN |
Cloudflare picks a connector per request; both are configured identically, so either one returns the same application. That is the whole trick: the apex survives joe-host because the HA box runs its own replica, not because HA lives on a different tunnel.
homeassistant (076a3313) and its add-on are deleted — tunnel gone, add-on uninstalled.
Do not recreate them; a second tunnel is a second writer.
The apex keeps its path rules — ^/vault, ^/ringbearer/webhook$, ^/nextchat-sync, the two
^/private_<token> routes — ahead of the bare-apex rule that lands on Home Assistant. No client
URL had to change.
Single source of truth
~/.hermes/cloudflared/ingress.yml (mode 600, never in git — it carries secret paths) is the only
ingress definition. RELEASE.json records its SHA-256. Deploy with
~/.hermes/scripts/cf-deploy-ingress.py, which validates, writes both copies, restarts both
connectors and verifies the hashes match. Never edit a live config by hand.
Origins are absolute LAN addresses (192.168.0.182, 192.168.0.155) so the file is
host-independent. No loopback, no container names.
What each failure costs
| Failure | Still reachable |
|---|---|
| joe-host VM down | HA at the apex and home; anything hosted on the HA box |
| joe-host connector down | everything, through the HA replica (verified 5 Nov: apex 200, /vault 200, webhook 401) |
| HA box down | every joe-host service; the apex goes with it |
| HA add-on down/updated | nothing — it is retired |
| Cloudflare / ISP / router down | nothing public; the LAN keeps working |
The apex has two connectors but one origin: HA on one box. A second HA instance would be the next step for availability, not another tunnel.
Health check
~/.hermes/scripts/cf-route-probe.py, daily 06:15 (no_agent=True). It asserts DNS ownership
(every hostname → homelab), that both replicas are present (amd64 + arm64), that the two
config files hash identically, and that real URLs fingerprint the applications. Silent when
healthy; a missing replica or a hash drift fails loudly with the hashes and CF-Ray.
Rules
- One tunnel, two replicas, one config file. Never introduce a second tunnel or a second writer.
homeis an alias for HA inside the shared ingress; it is not a separate deployment.- Path rules stay valid — the apex block is unchanged, so no client URL needs to move.
- The HA replica must never depend on joe-host to boot: it reads local files and starts from its
Docker restart policy (
unless-stopped). - Access policies attach to hostnames, so nothing here changes the login gate.