From a30c024ef8186bf62bbda24855f489bf768f83d2 Mon Sep 17 00:00:00 2001 From: dtoro Date: Sat, 8 Aug 2026 22:09:18 +0200 Subject: [PATCH] =?UTF-8?q?0.28.4=20=E2=80=94=20nomos=20healthcheck=20via?= =?UTF-8?q?=20binary=20subcommand=20(distroless=20has=20no=20wget)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nomos runtime image is gcr.io/distroless/static (no shell/wget), so the wget-based healthcheck (D5) could never run — nomos showed docker-unhealthy despite serving /healthz fine. Add a 'nomos healthcheck' subcommand that self-probes NOMOS_LISTEN/healthz (exit 0 on 200), and point the compose healthcheck at ["/nomos", "healthcheck"]. --- VERSION | 2 +- cmd/nomos/main.go | 26 ++++++++++++++++++++++++-- docker-compose.yml | 4 +++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index b79f04f..097bc93 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.28.3 +0.28.4 diff --git a/cmd/nomos/main.go b/cmd/nomos/main.go index aab9b93..9017709 100644 --- a/cmd/nomos/main.go +++ b/cmd/nomos/main.go @@ -183,8 +183,30 @@ func main() { <-ctx.Done() slog.Info("nomos: shutting down") - srv.Shutdown(context.Background()) - clientPool.closeAll() + srv.Shutdown(context.Background()) + clientPool.closeAll() + + case "healthcheck": + // Self-probe for Docker healthcheck. The nomos runtime image is + // distroless (no shell/wget), so the container can't run wget — the + // binary probes its own /healthz instead. Exit 0 on 200, 1 otherwise. + addr := os.Getenv("NOMOS_LISTEN") + if addr == "" { + addr = ":8092" + } + host := addr + if strings.HasPrefix(host, ":") { + host = "127.0.0.1" + host + } + client := &http.Client{Timeout: 3 * time.Second} + resp, err := client.Get("http://" + strings.TrimPrefix(host, "http://") + "/healthz") + if err != nil { + os.Exit(1) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + os.Exit(1) + } default: fmt.Fprintf(os.Stderr, "unknown command: %s\n", os.Args[1]) diff --git a/docker-compose.yml b/docker-compose.yml index 16d2e90..e647e0c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -233,8 +233,10 @@ services: stop_grace_period: 10s mem_limit: 512m cpus: 1.0 + # nomos runs on a distroless image (no shell/wget), so the healthcheck + # uses the binary's own `healthcheck` subcommand to self-probe /healthz. healthcheck: - test: ["CMD", "wget", "-q", "-O", "-", "http://127.0.0.1:8092/healthz"] + test: ["CMD", "/nomos", "healthcheck"] interval: 30s timeout: 5s retries: 3