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