diff --git a/CLAUDE.md b/CLAUDE.md index 6bf0f56..fa653de 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -141,12 +141,30 @@ of origins leaves only the last one allowed. It does not break the site — the frontend is same-origin and never consults CORS — so it is invisible until something else tries to call the API. Use `AllowOrigin::list`. +**The API binds the host's mesh address, never loopback and never `0.0.0.0`.** +The fleet has one firewalld default zone, so a wildcard bind plus the named +service would publish it on every address the host carries; and the edge proxy +is at another site, so loopback-only would not serve the site at all. Anything +probing `127.0.0.1:25864` gets connection-refused against a perfectly healthy +daemon — which is exactly how the first green build still failed its health +check. Use `$(hostname -f)`, which resolves to the mesh address. + **The edge proxy is at a different site from the API.** oolon (kosherinata) fronts the name; the API is on bob (hanzalova) because that is where the Planck -node lives. The deploy's loopback health probe cannot see that hop, so there is -a separate check that curls the API *from oolon*. A firewalld service scoped to +node lives. A health probe on the API host cannot see that hop, so there is a +separate check that curls the API *from oolon*. A firewalld service scoped to bob's own /16 would leave a live site with a dead `/v1` and nothing would fail. +**The edge proxy cannot reach its own public name.** From inside the mesh +`blackbeard.observer` resolves to the site's WAN address and dead-ends on the +OPNsense LAN interface (`reverse-proxies.md` §2). Verify the vhost with +`--resolve blackbeard.observer:443:127.0.0.1`, which still exercises the `:443` +stream router, SNI, the vhost, the cross-site hop and the API. + +**Runner labels.** `fedora-*` images have **no cargo** — Rust builds go on +`rust`, which is based on `runner-fedora-44` and so carries node + pnpm too. +Never `corepack enable`; pnpm is already on PATH (`gitea-runners.md` §4). + **WebSocket upgrade tests need `--http1.1`.** The vhost serves HTTP/2, and curl negotiates h2, where the `Connection: Upgrade` handshake is not how WebSockets work — you get a 400 from axum that looks like a proxy misconfiguration.