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, S3-compatible bucket, and persistent memory filesystem (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.

Memory storage

Compose shares the persistent memory-data volume between API, worker, and maintenance at /var/lib/omnara/memory. Across hosts, mount the same shared filesystem into API, every worker, and maintenance and set OMNARA_MEMORY_DIR to its absolute mount path. Configure services to wait for the mount before starting, and verify shared locking and file visibility between hosts. See Memory storage configuration for filesystem requirements. Keep the mount private to API, workers, and maintenance. Back up the entire memory directory alongside PostgreSQL.

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