Docs Operate
Self-host
Run the whole Runback stack on your own network with Docker Compose or Helm.
Self-hosted Runback is the same app as runback.dev, with its own Postgres, its own API layer and its own scheduler. Nothing leaves your network unless you configure it to.
db·postgres:16-alpine· 4 variablesrest·postgrest/postgrest:v12.2.3· 4 variablesproxy·caddy:2-alpine· 0 variablesweb·build: .· 56 variablesmigrate·build: .· 1 variablescheduler·alpine:3.20· 1 variable
| Service | From | Variables |
|---|---|---|
db | postgres:16-alpine | 4 |
rest | postgrest/postgrest:v12.2.3 | 4 |
proxy | caddy:2-alpine | 0 |
web | build: . | 56 |
migrate | build: . | 1 |
scheduler | alpine:3.20 | 1 |
JWT_SECRETPOSTGRES_PASSWORDAUTHENTICATOR_PASSWORDSUPABASE_SERVICE_ROLE_KEYAUDIT_SIGNING_KEYNEXT_PUBLIC_APP_URLCRON_SECRET
SSO_SECRET_KEYif any org configures OIDC SSOMODEL_KEY_SECRETif any org stores API keys in Settings › Keys and access › Model provider keys
Requirements
- Docker with Compose v2, or Kubernetes with Helm 3 (the chart is in
deploy/helm/runback). - The image builds on
node:22-alpine. To build or run the app outside Docker you need Node.js 22 or later; the repository'senginesfield is>=22. - Postgres comes with the stack (
postgres:16-alpine). Schema migrations run once per start in themigrateservice.
Bring it up
Copy the example settings
terminalShell cp .env.example .envSet the required variables
Set every variable in the first list above: Compose will not start without them. Generate each secret with
openssl rand -hex 32, and keepMODEL_KEY_SECRETdistinct fromAUDIT_SIGNING_KEY.Set the second list too if you are unsure:
MODEL_KEY_SECRETis needed before anyone saves a model key, andSSO_SECRET_KEYbefore anyone configures single sign-on. SetAUDIT_ED25519_PRIVATE_KEYso records are Ed25519-signed and anyone can check them; without it the audit log falls back to legacy HMAC (see Evidence).Start the stack
terminalShell docker compose up -dExpected outputThe services in the table above start, andmigrateexits once it has applied the schema.
Background jobs
The scheduler service runs the 21 jobs in selfhost/cron/crontab.template against the web container, authenticated with CRON_SECRET. They are the same jobs runback.dev runs.
Licence
Without RUNBACK_LICENSE the instance runs on the Community plan. An Enterprise licence is an Ed25519-signed token you paste into that variable; plan checks read it the same way the hosted app reads an org's plan.
Air-gapped installs
Set these in .env. docker-compose.yml passes each to the web container, and the Helm chart passes everything in its secret.
| Variable | Points the app at |
|---|---|
RUNBACK_SMTP_URL | Your mail server |
RUNBACK_OPENAI_BASE_URL | Your OpenAI-compatible endpoint |
RUNBACK_ANTHROPIC_BASE_URL | Your Anthropic-compatible endpoint |
RUNBACK_GROQ_BASE_URL | Your Groq-compatible endpoint |
RUNBACK_REPLAY_MODELS, RUNBACK_EXTRA_REPLAY_MODELS | The models replay may call |
RUNBACK_TSA_URLS | An internal RFC 3161 timestamp authority; unset, audit log checkpoints reach the two public defaults |
The base-URL overrides are RUNBACK_-prefixed on purpose, so an OPENAI_BASE_URL set for some other tool never redirects this deployment's model calls.
Recording through the gateway
The gateway records any agent's model calls with one base-URL change, and can hold the real provider key so your agent never sees it. Setting it up, keeping the key inside it, and replaying in CI are on the Gateway page.
Every variable, what it does and its default are in the environment reference.