Docs / Self-host
Self-hosting guide.
The Go backend, both SDKs, and the playbook content are MIT-licensed. If you'd rather not depend on the hosted Cloud version, you can run the whole stack yourself. This page is what you need to stand it up.
Prerequisites
- Go 1.25+ (
brew install goon macOS) - SQLite (bundled with Go, no install)
- Optional: Docker / a Linux host for production
Clone and run
git clone https://github.com/mesedi-ai/mesedi
cd mesedi/backend
# First run only: fetch deps
go mod tidy
# Run the service (creates mesedi-dev.db + runs migrations on first run)
go run cmd/api/main.go
The backend listens on :8080 by default and serves three things:
- The ingest API (executions, events, webhooks).
- A local-dev HTML dashboard at
/ui/. - A public
/healthliveness endpoint. It reports only that the process is running, and never touches the database, so that a load balancer polling it does not restart machines during a brief database problem. - A public
/readyreadiness endpoint. It pings the database and verifies every migration the build expects has been applied, returning503with a reason code when either fails. Point your uptime monitoring at/ready, not/health. A monitor watching/healthstays green through a total database outage.
Configuration
12-factor environment variables, with command-line flags overriding env vars:
MESEDI_PORT(default8080): TCP port the HTTP server binds to.MESEDI_LOG_LEVEL(defaultinfo): debug / info / warn / error.MESEDI_DB_URL: Postgres connection string. Empty for SQLite (the default during single-instance dev).MESEDI_DASHBOARD_URL: public origin of your Next.js dashboard. Used to construct playbook links in webhook payloads.
Point the SDK at your backend
In both SDKs, pass baseUrl / base_url to configure().
# Python
mesedi.configure(
api_key="mesedi_sk_...",
base_url="https://mesedi.yourdomain.com",
)
// TypeScript
configure({
apiKey: "mesedi_sk_...",
baseUrl: "https://mesedi.yourdomain.com",
});
Storage
The default is SQLite on a single persistent volume. Note that this is NOT what hosted Cloud runs: hosted Cloud moved to managed Postgres (Neon, AWS us-east-1) and the SQLite default is for self-hosting only. For single-instance, low-volume deployments this is sufficient: SQLite handles tens of millions of rows comfortably, and the dashboard's admin storage view shows utilization and per-project breakdown.
For multi-instance deployments and higher write concurrency, use Postgres by setting MESEDI_DB_URL to your Postgres connection string. Single-instance SQLite with a daily backup of the volume remains a fine choice for simpler deployments.
Auth and API keys
The local-dev environment bootstraps a fixed dev key (mesedi_sk_dev_local_only) on first run. This key is hardcoded and non-secret, never use it for anything other than local development. For real deployments, mint keys through the dashboard's API Keys page; only the prefix and a hash are stored.
What you give up
Self-hosting gives you full control over the data path and avoids any vendor lock-in. What you take on:
- Backups and disaster recovery. Cloud gets 24-hour point-in-time restore from Neon plus a nightly encrypted dump to off-site object storage; self-hosting means you build both.
- Upgrades. Pull, rebuild, redeploy. Schema migrations run on backend startup.
- Backend monitoring. The hosted version has external uptime monitoring via Better Stack; you'll want similar for your own deploy.
The hosted Cloud version handles all of the above for every Cloud tier. See pricing for the comparison.
What's next?
HTTP API reference covers the wire format your SDKs (or your hand-rolled instrumentation) post to the self-hosted backend.
Failure classes and playbooks explains the detectors that will run over the telemetry once it lands.