From 3b43393e5d98f5fc26819ad96dd4f37844296003 Mon Sep 17 00:00:00 2001 From: Jackson Roberts Date: Fri, 27 Feb 2026 18:07:26 -0600 Subject: [PATCH] fix: add /healthz endpoint to prevent K8s crash loop - Added dedicated /healthz route returning 200 OK - Skip API health check in hooks.server.ts for /healthz path - Updated K8s liveness/readiness probes to use /healthz instead of /login - The /login probe was returning 503 when the API was unreachable, causing Kubernetes to kill and restart the pod in a loop --- kubernetes/deployment.yaml | 6 ++++-- src/hooks.server.ts | 5 +++++ src/routes/healthz/+server.ts | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/routes/healthz/+server.ts diff --git a/kubernetes/deployment.yaml b/kubernetes/deployment.yaml index 43f541d..4d74712 100644 --- a/kubernetes/deployment.yaml +++ b/kubernetes/deployment.yaml @@ -35,15 +35,17 @@ spec: - containerPort: 3000 livenessProbe: httpGet: - path: /login + path: /healthz port: 3000 initialDelaySeconds: 5 periodSeconds: 15 + failureThreshold: 3 readinessProbe: httpGet: - path: /login + path: /healthz port: 3000 initialDelaySeconds: 3 periodSeconds: 5 + failureThreshold: 2 imagePullSecrets: - name: github-container-registry diff --git a/src/hooks.server.ts b/src/hooks.server.ts index cfb19c3..9191376 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -101,6 +101,11 @@ function apiUnreachablePage(): Response { } export const handle: Handle = async ({ event, resolve }) => { + // Let Kubernetes health probes pass without hitting the external API + if (event.url.pathname === "/healthz") { + return await resolve(event); + } + // Health-check the API before doing anything else. // /v1/teapot returns 418 when the API is alive. try { diff --git a/src/routes/healthz/+server.ts b/src/routes/healthz/+server.ts new file mode 100644 index 0000000..ee32eb8 --- /dev/null +++ b/src/routes/healthz/+server.ts @@ -0,0 +1,8 @@ +import type { RequestHandler } from "./$types"; + +export const GET: RequestHandler = async () => { + return new Response(JSON.stringify({ status: "ok" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); +};