GoRunner docs
Search or askSearch⌘K

Health checks

Four addresses that say whether GoRunner is up, and whether it can do its work.

Self-hosted

AddressAsked onAnswers
GET /api/healthYour installation’s address200 while the app runs.
GET /api/readyYour installation’s address200 when the app reaches its database and Redis. 503 when it can’t.
GET /healthzPort 9464 of each app and worker200 while the process runs.
GET /readyzPort 9464 of each app and worker200 when the process can work. A worker also needs its heartbeat from the last 90 seconds.

Point a load balancer, an ingress or an uptime monitor at /api/ready. It needs no token.

/healthz and /readyz answer only inside the Docker network, and only with METRICS_ENABLED=true. The app’s second process, api-twin, uses port 9465.

What the answer shows

Anyone who asks gets the status alone. /api/ready answers {"status":"ok"}, or {"status":"unavailable"} with 503. /api/health answers in the API’s usual shape, {"data":{"status":"ok"}}.

A request made on the server itself gets the version and each check. That means from inside the app, with no proxy in between. The setup and the update ask this way.

bash
docker compose exec api wget -qO- http://127.0.0.1:3001/api/ready
Output
{"status":"unavailable","version":"v2026.10.24","checks":{"database":{"ok":true,"ms":3},"redis":{"ok":false,"ms":2001,"error":"did not answer within 2s"}}}

Each check has 2 seconds. A failed check names its cause in a fixed phrase, such as connection refused or authentication failed, never the address or the user. The full message is in the app’s log.

The answer is reused for one second, so a load balancer and a burst of callers cost the database one ping.

Why does my proxy only get the short answer?

A request that carries X-Forwarded-For, X-Real-IP, Forwarded or True-Client-IP gets the short answer, even from the server itself. So a proxy that passes a caller’s header through can’t make a caller look local.

Can everyone see the details?

Set HEALTH_DETAILS=public in .env, then apply it with ./deploy.sh "$(cat VERSION)". On Kubernetes it is api.healthDetails: public. The probes work the same either way.