Open Status
Self-hosting Status

Self-hosting Status

Deploy the web application and workers, persist data, and upgrade.

Status runs as two processes: the web application (which stores configuration and history and serves the console) and one or more workers (which run the actual checks). Both ship from one Docker build.

Quickstart with Docker Compose

Shell
git clone <repository> status
cd status
docker compose up -d
docker compose logs web

The log prints a setup token:

Plain text
[status] This instance is not configured yet.
[status] Open /setup and enter this token: 9JjPVL7_Bm5FCmg6wTHueC9KBMOsmPFE

Open <http://localhost:3000/setup>, enter that token, and work through the wizard. It configures the database connection when none is set, then the public URL, private profile-picture storage, sign-in methods (email/password, SSO, or both), the first organization, and the shared worker token. Password deployments create their first owner in the wizard.

The token proves you can read the container's logs or filesystem, so an uninitialized instance cannot be claimed by whoever finds it first. It is deleted when setup completes, and both /setup and /api/setup/* return 404 from then on.

Finishing the worker

The wizard's workers step reveals the shared worker token once. Put it in a .env next to docker-compose.yml and restart the worker:

Shell
echo "MONITOR_WORKER_TOKEN=wrk_..." >> .env
docker compose up -d worker

Confirm it connected on the Agents page, or in the worker log:

Plain text
[worker] activated revision 4f53cda18c2b (3 monitors)
[worker] worker-1 v0.0.0 started in default; data=/var/lib/status-worker

Persistent data

Three volumes matter, for different reasons:

VolumeHoldsIf lost
postgres-dataAll configuration and historyEverything is gone. Back it up—see backup-restore.md.
web-stateSession secret, encryption key ring, wizard-saved database connection, and locally stored profile picturesStored credentials cannot be decrypted; local profile pictures are lost; a wizard-saved database URL must be re-entered.
worker-dataCached configuration and the outbound result queueQueued results not yet delivered are lost; the worker re-syncs and continues.

Store web-state on persistent storage and include it in backups. It is separate from PostgreSQL. Losing it makes encrypted credentials inaccessible.

The bundled deployment stores profile pictures in web-state. Multiple web replicas must use a shared filesystem or select S3-compatible storage in the wizard. Stored pictures remain private; browsers fetch them through Status after membership is checked.

Building the images directly

Shell
docker build --target web    -t status/web .
docker build --target worker -t status/worker .

Behind a reverse proxy

Set the public URL in the wizard (or Settings → Instance) to the origin users actually reach, and forward it to the container's port 3000. When SSO is enabled, it must match the redirect URI registered with your identity provider:

Plain text
https://status.example.com/api/auth/callback/authentik

Enable Trust proxy headers only when the proxy overwrites X-Forwarded-For. With it enabled behind a proxy that merely appends, clients can spoof their address and evade the IP-keyed rate limits.

Upgrading

Shell
docker compose pull
docker compose up -d

The image applies pending migrations on startup. If a migration fails the server refuses to serve rather than run against a half-migrated schema. Take a backup first—see backup-restore.md.

An existing deployment's .env keeps working unchanged: every environment variable that used to configure Status still overrides the corresponding database setting. See configuration.md for the precedence rules.