How to Self-Host openstatus
Problem
You want to run openstatus on your own infrastructure instead of using the hosted service. This gives you full control over your data, customization options, and the ability to monitor internal services not accessible from the public internet.
Solution
openstatus provides a Docker Compose setup that makes self-hosting straightforward. This guide walks you through deploying all necessary services and configuring your self-hosted instance.
Prerequisites
- Docker and Docker Compose installed
- Basic understanding of Docker and containerization
- Command line experience
- Git installed
Known limitations
Self-hosting openstatus currently has these constraints:
- It only works with private locations. You have to deploy our probes to the cloud provider of your choice.
- IP Restriction is not secure outside Vercel. The IP restriction feature for status pages relies on the
X-Forwarded-Forheader, which Vercel overwrites with the verified client IP. When self-hosting behind a different reverse proxy, clients can spoof this header to bypass IP restrictions. If you self-host and use IP restriction, ensure your reverse proxy strips and rewritesX-Forwarded-Forwith the real client IP before forwarding to openstatus.
Step-by-step guide
This guide is divided into three parts: launching the services, setting up the database and analytics, and configuring the application through the UI.
Part 1: Initial Setup and Service Launch
-
Clone the Repository
Get the latest version of openstatus:
git clone https://github.com/openstatushq/openstatus cd openstatus -
Configure Your Environment
Copy the example environment file. This file will hold all your configuration variables.
cp .env.docker.example .env.dockerOpen
.env.dockerin a text editor. At a minimum, you must set a value forAUTH_SECRETfor authentication to work. For a complete setup, review the file for other variables like OAuth providers or email services. -
Build and Start Services
Use Docker Compose to build and run all openstatus services in the background.
export DOCKER_BUILDKIT=1 docker compose up -dYou can check the status of the services with
docker compose ps. It might take a few minutes for all services to be healthy.
Part 2: Database and Analytics Setup
-
Run Database Migrations
The database container starts with an empty database. You must run migrations to set up the required schema.
# Make sure you are in the root of the openstatus project cd packages/db pnpm install pnpm migrate cd ../.. # Return to the project rootIf you do not have or want to avoid installing the necessary tools on the host, you can run this command to create a one-shot container that will remove itself after completion.
# Make sure you are in the root of the openstatus project # For RHEL derivatives, make sure to end /work with :Z for SELinux, "$PWD":/work:Z sudo docker run --rm -it \ --network openstatus \ --env-file .env.docker \ -v "$PWD":/work \ -w /work/packages/db \ node:22-trixie \ bash -lc ' set -euo pipefail export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq curl ca-certificates unzip curl -fsSL https://bun.sh/install -o /tmp/bun-install.sh bash /tmp/bun-install.sh export PATH="$HOME/.bun/bin:$PATH" npm i -g pnpm pnpm install bun src/migrate.mts ' -
Deploy Local Tinybird Analytics
Tinybird is used for analytics. Deploy the local datasources, pipes, and endpoints.
# Make sure you are in the root of the openstatus project cd packages/tinybird pnpm install tb --local deploy cd ../.. # Return to the project root -
Configure Tinybird API Key
You need to get your local Tinybird admin token and add it to your environment file.
cd packages/tinybird tb --local open # This opens the Tinybird UI in your browserIn the Tinybird UI, find and copy your admin token. Then, add it to your
.env.dockerfile in the root of the project:TINY_BIRD_API_KEY="your-tinybird-admin-token"After adding the token, restart your services for the changes to take effect:
# Make sure you are in the root of the openstatus project docker compose restart
Part 3: Application Configuration
Now that the services are running, you can access the dashboard and perform the final setup steps.
- Dashboard:
http://localhost:3002 - Status Pages:
http://localhost:3003
-
Create a Workspace and Set Limits
- Navigate to the dashboard at
http://localhost:3002. - Sign up and create a new workspace.
- Because this is a self-hosted instance, you need to manually set the feature limits for your workspace directly in the database.
The following command updates the limits for the workspace with
id = 1. If your workspace has a different ID, change theWHERE id = 1part of the command.curl -X POST http://localhost:8080/ -H "Content-Type: application/json" \ -d '{"statements":["UPDATE workspace SET limits = '\''{\\"monitors\\":100,\\"periodicity\\":[\\"30s\\",\\"1m\\",\\"5m\\",\\"10m\\",\\"30m\\",\\"1h\\"],\\"multi-region\\":true,\\"data-retention\\":\\"24 months\\",\\"status-pages\\":20,\\"maintenance\\":true,\\"status-subscribers\\":true,\\"custom-domain\\":true,\\"password-protection\\":true,\\"white-label\\":true,\\"notifications\\":true,\\"sms\\":true,\\"pagerduty\\":true,\\"notification-channels\\":50,\\"members\\":\\"Unlimited\\",\\"audit-log\\":true,\\"private-locations\\":true}'\'' WHERE id = 1"]}'You can find your workspace ID by inspecting the database with a command like
curl -X POST http://localhost:8080/ -H "Content-Type: application/json" -d '{"statements":["SELECT id, name FROM workspace"]}'.If you want to unlock the paid features, you need to upgrade your workspace inside the database. The following command assumes that you want to change the payment plan for the workspace with the ID of 1, and that you want to change it to a "Pro" instance indefinitely.
curl -sS -X POST "http://localhost:8080/" \ -H "Content-Type: application/json" \ -d "{\"statements\":[ \"UPDATE workspace SET plan='team', paid_until=strftime('%s','now') + 315360000, ends_at=NULL WHERE id=1;\", \"SELECT id, plan, paid_until, ends_at FROM workspace WHERE id=1;\" ]}" - Navigate to the dashboard at
-
Deploy a Private Location
The self-hosted version relies on private locations to perform checks.
- In the dashboard, navigate to Settings -> Private Locations and create a new one.
- Copy the generated
OPENSTATUS_KEY. - Deploy the private location probe to your infrastructure using the Docker image
ghcr.io/openstatushq/private-location:latest. - When deploying, you must provide two environment variables to the container:
OPENSTATUS_KEY: The key you just copied.OPENSTATUS_INGEST_URL: The URL of your self-hosted server's API endpoint (e.g.,http://<your-server-ip-or-domain>:3001).
- For a detailed guide on deploying a private location, see Deploy Private Locations on Cloudflare Containers.
-
Create Monitors
You're all set! You can now create monitors in the dashboard. They will be checked by the private location you deployed.

Service architecture
openstatus consists of multiple services running together:
| Service | Port | Purpose |
|---|---|---|
| workflows | 3000 | Background jobs and scheduled tasks |
| server | 3001 | API backend (tRPC) |
| dashboard | 3002 | Admin interface for configuration |
| status-page | 3003 | Public status pages |
| private-location | 8081 | Monitoring agent for checks |
| libsql | 8080 | Database (HTTP) |
| libsql | 5001 | Database (gRPC) |
| tinybird-local | 7181 | Analytics and metrics |
What you've accomplished
Congratulations! You've successfully:
- ✅ Deployed openstatus on your own infrastructure
- ✅ Configured all required services
- ✅ Set up a private location for monitoring
- ✅ Created your first self-hosted monitor
Troubleshooting
Containers won't start: Check Docker logs with docker compose logs [service-name]
Database migrations fail: Ensure you're in the correct directory and have pnpm installed
Private location not connecting: Verify the OPENSTATUS_KEY and OPENSTATUS_INGEST_URL are correct
Tinybird issues: Make sure the Tinybird token is correctly set in .env.docker
Next steps
- Deploy Private Locations - Set up monitoring from multiple regions
- Create Monitors - Start monitoring your services
Additional resources
- Docker Compose file - Review the complete configuration
- Private Location Reference - Technical specifications
- Join our Discord - Get help from the community