SKYHOUSE.dev Journal

Maintaining the Cloud Fortress

DNS reliability overhaul: one updater, short TTL, server self-resolution, and a recovery-verification notifier

Why: After a public-IP change, the site and all subdomains were intermittently unreachable for hours — and the Telegram alert just said "updating DNS" with no follow-up on whether it actually recovered. This is the recurring DNS/IP failure mode; the goal here was to make an IP change a fully hands-off event with a clear "you're back up" (or "needs you") signal.

Builds on the earlier DDNS consolidation. Several compounding causes, fixed in layers.

1. What was actually wrong

2. Short TTL + forced nameserver re-sync

Added --ttl and --force flags to /home/plex/bin/dynadot-update.py, then re-pushed the records idempotently (same apex A + wildcard CNAME) with TTL 600 → 120. The re-push bumped the SOA serial, forcing Dynadot to re-propagate to both nameservers; the shorter TTL means future changes clear in ~2 min instead of ~10. ddns-go's own configured TTL was also set to 120 so it doesn't revert on its next update. (Caveat logged: ddns-go's config lives inside the container with no host bind-mount, so a container recreate would wipe the TTL setting and the Dynadot API key — worth giving it a volume later.)

3. The server now resolves its own domains over the LAN

4. A real recovery notifier

New /home/plex/bin/ip-recovery-verify.sh, launched (detached) by ip-watch.sh the moment an IP change is seen. It polls until the new IP is genuinely live to the public — public DNS propagated (1.1.1.1 + 8.8.8.8) AND the site loads from outside (check-host.net, ≥2 external nodes returning 200) — then sends a Telegram ✅ "back up and publicly reachable". If it doesn't recover within 40 min it sends a ⚠️ with concrete manual steps (router port-forward → 192.168.1.136, check ddns-go, check Dynadot). The initial alert now sets expectations: "nothing for you to do — I'll confirm when it's verified back up, or tell you if it needs a manual look."

5. The IP-change flow now (all automated)

  1. ISP changes the public IP.
  2. ddns-go (polls ~5 min) updates the Dynadot apex A record (TTL 120). Wildcard CNAME carries every subdomain.
  3. Dynadot propagates to its nameservers; public resolvers refresh within ~2 min of TTL expiry.
  4. Router port-forward (80/443 → 192.168.1.136) is LAN-side and IP-independent; NPM, certs, services untouched.
  5. ip-watch.sh (polls 5 min) sends the heads-up and launches the verifier, which sends the ✅ when externally confirmed.
  6. LAN/server access never blips — it uses /etc/hosts → LAN IP throughout.

Manual steps in the normal case: none. The only hands-on scenarios are the ⚠️ path (e.g., the ISP reset the router's port-forward) or a Dynadot nameserver that won't converge (registrar-side — a support ticket).

Net: an IP change is now a hands-off event with a verified "you're back up" signal, the server never loses sight of its own services, and propagation windows shrank from ~10 min to ~2.

← Back to Admin Hub