Skip to content

Restart the runtime and check its health

View as Markdown

This guide restarts a self-hosted runtime without losing runs, and checks that it came back healthy.

  • A runtime running as Self-host Kindgi sets it up: the kindgi-server, kindgi-db and kindgi-pack containers, on the kindgi network, with kindgi.env and pack.env.
  • Docker and curl, on the machine that runs the containers.
  • KINDGI_API_TOKEN exported in your shell as the runtime's API token. The commands that take your API token read it from there.
  • For kindgi commands: Kindgi 0.1's CLI, which runs from any folder as npx --yes @kindgi/cli@0.1 (Install). Inside a pack project, pnpm exec kindgi runs the project's pinned CLI instead.

The runtime reads its settings when it starts, so most changes to kindgi.env take a restart.

Stop the container, remove it, and start it again with the same settings:

Terminal window
docker stop -t 30 kindgi-server
docker rm kindgi-server
docker run -d --name kindgi-server --network kindgi --restart unless-stopped \
--add-host registry.localhost:host-gateway \
-p 127.0.0.1:4000:4000 --env-file kindgi.env \
quay.io/kindgi/runtime:0.1.9
  • -t 30 gives the runtime 30 seconds to stop before Docker kills it.
  • --network kindgi puts it on the network the database and the pack's service are on.
  • --restart unless-stopped starts it again after a crash or a reboot.
  • --add-host registry.localhost:host-gateway lets it reach the local registry that Self-host Kindgi pushes the pack to.
  • -p 127.0.0.1:4000:4000 serves the API on this machine's port 4000 only.
  • --env-file kindgi.env gives it its settings.

Docker prints the container's name after stop and rm, and the new container's id after run:

kindgi-server
kindgi-server
22451a46ab6068874f5e493d44d3cb2fefc38edfcac32553194206eac95ea229

On a stop, the runtime stops taking requests and gives the runs it's executing up to 7 seconds to finish. Then it exits with code 0.

Two routes say whether the runtime is up, and its log says why when it isn't. The log lines on this page are in the pretty format. A runtime in a container logs JSON unless KINDGI_LOG_FORMAT=pretty is set. Logs has both formats, the levels, and how to follow one request.

/health says the process is up. Neither it nor /ready needs a token:

Terminal window
curl -s http://localhost:4000/health

-s keeps curl quiet, so it prints only the answer:

{"ok":true}

/ready says its database answers too, within two seconds:

Terminal window
curl -s http://localhost:4000/ready
{"ok":true,"database":"ok"}

While Postgres is unreachable, /ready answers 503 with {"ok":false,"database":"unreachable"}, and /health still answers {"ok":true}.

Point a load balancer's or a platform's readiness check at /ready, or /health, and never at /. / leads to the console with a 302. Without the console, it answers 200 even while the database is down, so a check on / would pass a broken runtime.

The image's own health check uses /ready, so docker ps shows the runtime's state:

Terminal window
docker ps --filter name=kindgi-server --format 'table {{.Names}}\t{{.Status}}'

--filter picks the runtime's container, and --format prints its name and status:

NAMES STATUS
kindgi-server Up 34 seconds (healthy)

docker ps shows (unhealthy) while the database is down, and the runtime's log says why:

17:37:34.151 WARN [ready] the database doesn't answer: no answer within 2000 ms

A route that reads the database answers 500 and names the cause. With Postgres unreachable, GET /v1/deployments answers:

Terminal window
curl -s http://localhost:4000/v1/deployments -H @<(printf 'Authorization: Bearer %s\n' "$KINDGI_API_TOKEN")
{"error":{"code":"internal-server-error","message":"Deployment list failed: deployments: Tenant-scoped query failed: host not found (getaddrinfo ENOTFOUND kindgi-db)","requestId":"req-…"}}
Excerpt

The runtime prints what it's running with when it starts. Read it with docker logs kindgi-server. In the JSON format, they're the lines of its boot record. The lines to check after a change:

Token: kgi_bt_…3236 (provided)
…
Public run tokens: off (no signing key)
…
License: …
…
Env: production (tool secrets resolve in it)
Tenant host access: deployed (stdio MCP endpoints refused; tenant-chosen hosts can't reach the metadata server or this host; KINDGI_TENANT_HOST_ACCESS)
Pack service: http://…:8080 — acme-pack (artifact …), protocol 2, 3 tools, 1 check
Excerpt
  • Token: the last four characters of the API token it accepts.
  • License: who the key is for, its kind and its end date. A warning follows within 30 days of the end.
  • ⚠ This preview build (…) stops starting on …: from 30 days before this release stops starting (90 days after it was released, until Kindgi 1.0). Upgrade before then. In the JSON format it's also a record of its own, "event": "kindgi.preview_expiry", logged at startup and once a day: match it in a log alert.
  • Pack service: the pack it reached, with its artifact version. When it can't reach it, a warning takes this line's place, with the reason.

When the runtime comes back after stopping without a shutdown, its sweep repairs the runs the stop left mid-way, as If the runtime stops explains. Each repair is a line in its log:

<time> INFO [leases] resuming run <run id> (tenant <tenant id>): its wait resolved and nothing resumed it
<time> INFO [leases] woke the flow run waiting on child run <run id> …: the child had moved on
<time> INFO [leases] ended run <run id> …: its parent run had ended
Excerpt
  • A setting the runtime refuses, such as a missing license key, or a log setting it can't use: it exits with code 2, and its log says what to fix.

  • A database it can't reach while starting: it exits with code 1, and its log says which database and why, never the password. Here Postgres wasn't running:

    Terminal window
    docker inspect --format '{{.State.ExitCode}}' kindgi-server
    docker logs kindgi-server
    1
    Can't connect to the database at kindgi-db:5432/kindgi: host not found (getaddrinfo ENOTFOUND kindgi-db). Check KINDGI_DATABASE_URL, and that Postgres is up and reachable from here.
  • Another failure while starting: it exits with code 1, and the log's first line starts with kindgi-runtime: fatal: and ends with the cause.

  • A run that fails: its failureMessage, in npx --yes @kindgi/cli@0.1 runs get <run id>.