Skip to main content
Self-hosting means running four long-lived Omnara services plus a one-shot migration job, pointed at your own Postgres, Redis, and S3-compatible bucket (Architecture), with one public URL in front of them.

Quick start (local)

The repository’s compose file runs everything behind the app profile:
That builds from source (a checkout auto-loads compose.override.yaml). To run published release images instead, use the base file alone, optionally pinning a release with OMNARA_RELEASE:
Open http://localhost:8000 and sign up — the local email driver is console, so the verification link will appear in docker compose logs api.

Production database upgrades

Run the release’s one-shot migrate image before starting its API, worker, and maintenance services. Connect the migrator directly to the PostgreSQL writer; do not use RDS Proxy or transaction-pooling PgBouncer. Long-running services may use a compatible proxy. See database configuration for connection-pool defaults.

Exposing the deployment publicly

OMNARA_PUBLIC_URL is the public app origin used for email links, OAuth callbacks, and browser flows. The API defaults to the same deployment at /api/v1; set OMNARA_PUBLIC_API_URL when it is exposed at a different public URL. The daemon installer is served from the API origin at /install/omnarad.sh. These features will not function unless the configured URLs are publicly accessible.
Set OMNARA_PUBLIC_URL on every backend service. Outside local development it is required.

Cloudflare Tunnel

One easy option to expose Omnara publicly is via a Cloudflare Tunnel. For a stable origin, add a domain to Cloudflare and create a named tunnel:
Then, restart the stack pointed at the tunnel’s URL:
cloudflared service install will keep a named tunnel running across reboots. Any other reverse proxy or tunnel (Caddy, nginx, Tailscale Funnel, ngrok) works the same way, as long as it forwards the public Host header — the API rejects hosts it doesn’t recognize.

Quick Tunnel

For a temporary tunnel without a separate domain, you can use:
This prints a random https://{subdomain}.trycloudflare.com URL that changes every run. After starting the tunnel you can set OMNARA_PUBLIC_URL in the same way described above.

Next steps

Configuration

The full environment-variable reference

Architecture

The control-plane processes and stores