From 62817efa6e012788ff6d8287d043f20c9f602652 Mon Sep 17 00:00:00 2001 From: Aarnav Tale Date: Sat, 30 May 2026 20:46:32 -0400 Subject: [PATCH] feat: gate the healthcheck listen file to docker only --- Dockerfile | 7 +++++++ app/server/main.ts | 21 +++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 375cfe2..336a7ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,6 +57,11 @@ COPY --from=go-base /bin/hp_healthcheck /bin/hp_healthcheck HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD ["/bin/hp_healthcheck"] +# Tells Headplane to publish its loopback healthcheck URL to this +# file on startup; `hp_healthcheck` reads it. Docker-only — native +# installs don't ship a consumer. +ENV HEADPLANE_LISTEN_FILE=/tmp/headplane-listen + WORKDIR /app CMD [ "/app/build/server/index.js" ] @@ -73,5 +78,7 @@ COPY --from=go-base /bin/hp_healthcheck /bin/hp_healthcheck HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \ CMD ["/bin/hp_healthcheck"] +ENV HEADPLANE_LISTEN_FILE=/tmp/headplane-listen + WORKDIR /app CMD [ "node", "/app/build/server/index.js" ] diff --git a/app/server/main.ts b/app/server/main.ts index e6766ef..958906f 100644 --- a/app/server/main.ts +++ b/app/server/main.ts @@ -42,17 +42,26 @@ if (certPath || keyPath) { } } -// Read by the bundled Docker healthcheck. Includes the basename -// (`__PREFIX__`) so the Go binary can stay completely dumb — just -// GET whatever URL is in this file. `/tmp` is writable in -// distroless and in every dev shell we care about. -const healthURL = `${tls ? "https" : "http"}://127.0.0.1:${config.server.port}${__PREFIX__}/healthz`; +// `HEADPLANE_LISTEN_FILE` is a Docker-specific contract: the +// Dockerfile sets it to `/tmp/headplane-listen` so the bundled +// `hp_healthcheck` binary can discover the URL to probe. Native +// installs don't ship a consumer, so we just skip writing anything +// if the var isn't set. +const listenFilePath = process.env.HEADPLANE_LISTEN_FILE; +const listenFile = listenFilePath + ? { + path: listenFilePath, + // Full URL including `__PREFIX__` so the Go binary can GET it + // verbatim — no path joining, no basename knowledge needed. + url: `${tls ? "https" : "http"}://127.0.0.1:${config.server.port}${__PREFIX__}/healthz`, + } + : undefined; startHttpServer({ host: config.server.host, port: config.server.port, tls, - listenFile: { path: "/tmp/headplane-listen", url: healthURL }, + listenFile, listener: composeListener({ basename: __PREFIX__, staticRoot: clientDir,