--- title: 'Running the runtime' description: 'The health endpoints an orchestrator probes, the environment the runtime injects, and how the same surface behaves locally.' position: 6 --- # Running the runtime > What an orchestrator probes to decide the container is alive, what the > runtime puts in the environment for your code, and how the same contract > behaves under a local run. ## Health and liveness The workspace splits liveness from health: | Route | Behaviour | | ------------- | --------------------------------------------------------------------------------------------------------------- | | `GET /live` | Instant `200 { status: "ok" }`. No probes, no awaits: the platform liveness signal. | | `GET /health` | Runs every subsystem probe in parallel. `200 { status: "ok", checks }` or `503 { status: "degraded", checks }`. | The deep `/health` reports the subsystems your workspace depends on. Each check is `{ "status": "ok" }`, or `{ "status": "error", "detail": "…" }` with the reason it failed: ```jsonc { "status": "ok", "checks": { "database": { "status": "ok" }, "redis": { "status": "ok" }, }, } ``` A single failing subsystem degrades the whole response to `503`. The platform uses `/live` for the liveness probe so a slow subsystem never gets the container recycled by mistake. Both routes belong to the deployed workspace image. `stackbone dev` serves a lighter `GET /api/health` instead, which answers `{ "status": "ok" }` as soon as the emulator is up. ## Runtime environment The runtime injects these into the container as a behavioural contract. You read them, you never set them: | Variable | What it is | | ---------------------------------------------------- | -------------------------------------------------------------------------------- | | `STACKBONE_INSTALLATION_ID` | the install this container serves | | `STACKBONE_API_URL` | the control-plane URL the SDK talks to | | `DATABASE_URL` | the per-install Postgres connection (the agents' + workflows' data plane) | | `WORKFLOW_REDIS_URL` | the per-install Redis backing durable workflow runs | | `MODEL_PROVIDER_API_KEY` / `MODEL_PROVIDER_BASE_URL` | the model gateway credentials an agent reads | | `STACKBONE_SECRET_KEY` | the per-agent key every stored secret is encrypted with | | `STACKBONE_S3_*` | endpoint, keys, bucket and region of the object store `client.storage` writes to | `STACKBONE_S3_FORCE_PATH_STYLE` sits in that last group and decides how the bucket is addressed. It defaults to `true`, which puts the bucket in the path (`https://host/bucket/key`). Set it to `false` for a backend that only answers to the bucket-as-subdomain form, such as AWS S3 or Railway Buckets. Most code never reads these: the ambient `stackbone` client (`stackbone.database`, `.secrets`, `.config`, …) wires them for you. The image binds **8080**, or `PORT` when the host sets one, so a platform that assigns the port needs no extra configuration. A `PORT` that is not a usable port number fails the boot instead of falling back, since binding 8080 anyway would leave the platform health-checking a port nothing listens on. See [What you set on the deployed container](/docs/cli/reference/package#what-you-set-on-the-deployed-container). > The runtime also serves `GET /api/contract`, the Stackbone Agent Protocol > handshake that advertises the agent-facing `stackbone.*` capabilities > (database, storage, rag, secrets, …). That is the SDK capability handshake; > it is distinct from the HTTP endpoints above that **you** drive (chat, > workflows, runs, hooks). ## Local development `stackbone dev` brings up the same contract on `http://127.0.0.1:4242`: the chat endpoints and the workflow start/chat routes, all agents running in-process behind one server. The local stack is Postgres + Redis + MinIO. There is nothing to install or sign by hand, and the emulator accepts any non-empty bearer key. See [Local development](/docs/cli/guides/local-development) for the local loop and [Getting started](/docs/cli/guides/getting-started) to scaffold a workspace.