Docs menuSelf-host

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.

What docker compose up starts
  • db · postgres:16-alpine · 4 variables
  • rest · postgrest/postgrest:v12.2.3 · 4 variables
  • proxy · caddy:2-alpine · 0 variables
  • web · build: . · 56 variables
  • migrate · build: . · 1 variable
  • scheduler · alpine:3.20 · 1 variable
6 services
ServiceFromVariables
dbpostgres:16-alpine4
restpostgrest/postgrest:v12.2.34
proxycaddy:2-alpine0
webbuild: .56
migratebuild: .1
scheduleralpine:3.201
Compose will not start without (7)
  • JWT_SECRET
  • POSTGRES_PASSWORD
  • AUTHENTICATOR_PASSWORD
  • SUPABASE_SERVICE_ROLE_KEY
  • AUDIT_SIGNING_KEY
  • NEXT_PUBLIC_APP_URL
  • CRON_SECRET
Required by web when you use the feature (2)
  • SSO_SECRET_KEY if any org configures OIDC SSO
  • MODEL_KEY_SECRET if any org stores API keys in Settings › Keys and access › Model provider keys
The web service passes 56 variables in all; the rest are optional. Compose passes every air-gap variable.

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's engines field is >=22.
  • Postgres comes with the stack (postgres:16-alpine). Schema migrations run once per start in the migrate service.

Bring it up

  1. Copy the example settings

    terminalShell
    cp .env.example .env
  2. Set 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 keep MODEL_KEY_SECRET distinct from AUDIT_SIGNING_KEY.

    Set the second list too if you are unsure: MODEL_KEY_SECRET is needed before anyone saves a model key, and SSO_SECRET_KEY before anyone configures single sign-on. Set AUDIT_ED25519_PRIVATE_KEY so records are Ed25519-signed and anyone can check them; without it the audit log falls back to legacy HMAC (see Evidence).

  3. Start the stack

    terminalShell
    docker compose up -d
    Expected output
    The services in the table above start, and migrate exits 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.

VariablePoints the app at
RUNBACK_SMTP_URLYour mail server
RUNBACK_OPENAI_BASE_URLYour OpenAI-compatible endpoint
RUNBACK_ANTHROPIC_BASE_URLYour Anthropic-compatible endpoint
RUNBACK_GROQ_BASE_URLYour Groq-compatible endpoint
RUNBACK_REPLAY_MODELS, RUNBACK_EXTRA_REPLAY_MODELSThe models replay may call
RUNBACK_TSA_URLSAn 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.

Last updated 2 Nov 2026.