relay: bind 169.254.1.2 (host.containers.internal), not loopback

A socket bound to 127.0.0.1 refuses container traffic that arrives via
the podman bridge: the first live webhook failed with 'dial tcp
169.254.1.2:18093: connection refused'. The relay now binds the
host-gateway endpoint — link-local to the podman bridge, off the LAN —
and the deployer's health probe follows it there.
This commit is contained in:
Frank committed 2026-09-17 13:26:24 -07:00
1 parent 5f55efcb9d
commit 8f747a2104
9 files changed
+31 -21

No files matched your search

@@ -19,7 +19,7 @@ Alertmanager receives firing rules from Prometheus, groups and dedupes them, and
## Why the webhook address is `host.containers.internal`
The Signal relay is a host-side process on the host's **loopback** (127.0.0.1:18093). From a bridge container, loopback is the container's own, and netavark DNATs *published* ports only — so the LAN IP and the podman gateway both refuse an unpublished host bind. `host.containers.internal` (169.254.1.2) is the one address that reaches a host-local listener from a bridge container. The relay listens on loopback only, so the unauthenticated webhook endpoint stays off every host interface.
The Signal relay is a host-side process, and the address it must bind is the one detail this design gets wrong once: **127.0.0.1 does not work**. From a bridge container, loopback is the container's own, and netavark DNATs *published* ports only — the LAN IP and the podman gateway are both refused for an unpublished host bind. `host.containers.internal` (169.254.1.2) is the one address that reaches a host-local listener from a bridge container, so the relay binds *that* address (measured 2026-09-17: a loopback bind refused the first webhook with `dial tcp 169.254.1.2:18093: connection refused`). 169.254.1.2 is link-local to the podman bridge — not on loopback, not on any LAN interface, reachable only from this host's containers — so the unauthenticated webhook endpoint stays off the wire.
## The Signal relay
@@ -36,7 +36,7 @@ The Signal relay is a host-side process on the host's **loopback** (127.0.0.1:18
./scripts/deploy.sh dankclaw --service alertmanager
```
`deploy_observability` installs the quadlet unit, `copy_alertmanager_config` installs the config, and `install_signal_relay` copies the user unit, enables and restarts it, then waits on `127.0.0.1:18093/health` before the container's own `/-/healthy` wait. The planner selects `alertmanager` for its quadlet file, `shared/prometheus/alertmanager.yml`, and the two relay files; `prometheus` ships the `alerting:` block that points at `alertmanager:9093`.
`deploy_observability` installs the quadlet unit, `copy_alertmanager_config` installs the config, and `install_signal_relay` copies the user unit, enables and restarts it, then waits on `169.254.1.2:18093/health` before the container's own `/-/healthy` wait. The planner selects `alertmanager` for its quadlet file, `shared/prometheus/alertmanager.yml`, and the two relay files; `prometheus` ships the `alerting:` block that points at `alertmanager:9093`.
## Gotchas