DC-044: fix /health/ready caddy probe false negative

The caddy.ok check in /health/ready probed /config/ (51KB) and timed out
at 3s with "This operation was aborted" while Caddy admin was actually
healthy. Two underlying issues:

1. Native undici fetch() rejects connections to :2019 (Caddy admin). Use
   fetchT() which falls back to raw http.request for the admin port.
2. /config/ is heavy and head-of-line blocks when /load is in flight.
   Switch to /config/apps/http/servers/srv0/listen (9 bytes) and bump
   timeout to 10s.

Verified on DNS2 2026-07-09: direct Caddy admin curl 200 in 3ms,
/health/ready was aborting at 3s. After fix: /health/ready caddy.ok
true in <100ms.

Caddyfile change (/etc/caddy/Caddyfile) added /dashcaddy-login to the
@needsAuth not path exclude so direct hits to the auto-login landing
page render the page instead of getting gate-redirected to a blank
302 — applied and reloaded via POST /load earlier this session.
This commit is contained in:
Krystie
2026-07-08 21:33:06 -07:00
parent e036bfe452
commit d539ee3b08
3 changed files with 8 additions and 14 deletions
+6 -6
View File
@@ -727,14 +727,14 @@ async function createApp() {
}
// Check 4: Caddy admin API reachable
// Use fetchT() (NOT native fetch) because undici fetch rejects Caddy admin
// on :2019, and probe the LIGHTEST endpoint (srv0/listen = 9 bytes) to avoid
// head-of-line blocking when /load or another config mutation is in flight.
// A previous `/config/` probe hit the 3s AbortController timeout with
// "This operation was aborted" while Caddy was actually healthy.
try {
const caddyUrl = config.CADDY_ADMIN_URL || 'http://localhost:2019';
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 3000);
const response = await fetch(`${caddyUrl}/config/`, {
signal: controller.signal
});
clearTimeout(timeout);
const response = await fetchT(`${caddyUrl}/config/apps/http/servers/srv0/listen`, {}, 10000);
checks.caddy = { ok: response.ok, status: response.status };
if (!response.ok) allOk = false;
} catch (e) {