setup-node-ca.sh writes one 'listen <addr>:443 ssl;' per LAN address at
the moment it runs (per-address on purpose — Tailscale holds :443 on the
tailnet address) and its idempotency guard never revisits them. nginx
REFUSES TO START while any listen address is missing, so this takes the
entire dashboard down, not just HTTPS:
1. the node moves networks and the old address is gone; or
2. nginx starts before DHCP assigns the address — and nginx.service
ships no Restart=, making that single race permanent.
Both hit archi-dev-box today: nginx dead since boot on 'bind() to
192.168.63.240:443 failed (99: Cannot assign requested address)', the
dashboard simply unreachable, which is exactly the symptom a user with
no screen cannot diagnose.
run_nginx_listener_repair drops listeners for absent addresses, adds one
per present address (CGNAT excluded), installs behind with
rollback, then starts nginx if it is down and gives it a
Restart=on-failure drop-in so the boot race stops being fatal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both failure modes are from framework-pt relocating (2026-08-15):
- archy-ha-btc-rpc-proxy bound socat to the LAN IP baked in at unit
generation; after a move the address no longer exists and the unit
restart-looped forever (counter 2446). run_ha_rpc_proxy_bind_repair
rewrites ExecStart to compute the bind address at each start, so
Restart=always itself heals any future move.
- homeassistant's quadlet pointed at the domain image ref with --pull
never while local storage held the same name:tag under the bare-IP
registry ref (catalog signing rename) — 761 restarts on 'image not
known'. run_pull_never_image_repair retags a matching local image;
it deliberately never pulls.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The welcome banner picked its address with 'hostname -I | awk {print $1}',
so a node with WireGuard up advertised 10.44.0.1 — its own tunnel address,
present on EVERY node — as its web ui / ssh address. Off-tunnel that is
unreachable, and after a headless box moves to a new network it is exactly
the wrong thing to trust (framework-pt, 2026-08-15).
- Pick the default route's source address; fall back to the first address
that is not WireGuard 10.44/16, CGNAT 100.64/10, or loopback.
- Also print http://<hostname>.local when avahi is up — the one address
that survives any DHCP change, which is the real answer for headless
boxes that move between networks.
- scripts/welcome-banner.sh is the new canonical copy, embedded in the
binary (tor-helper pattern): bootstrap::run_welcome_banner_sync rewrites
/etc/profile.d/archipelago.sh on ISO-installed nodes at startup, so the
fix reaches the deployed fleet with the next OTA instead of only fresh
ISOs. Machines without an installer-baked banner are left untouched.
- Same fix inlined in the live ISO builder's PROFILE heredoc
(image-recipe/_archived/build-auto-installer-iso.sh).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>