Skip to content

Self-hosting

Ony.ai’s open-source core (AGPL-3.0) runs entirely on your own infrastructure, with your own domain, telephony carrier, models, and database. Nothing depends on ony.ai.

There are two supported ways to run the control plane. Pick by team size and durability needs, not by feature: the OSS core is fully featured in both.

One person, zero dependencies. Install from PyPI and start a full Ony.ai server on SQLite. No Docker, Postgres, or Valkey is required (those stores fall back to in-memory), and ony up generates its own signing secret on first run.

Terminal window
pip install ony
ony up # full server on SQLite; prints the local URL

Then, from a project directory, enroll the machine and wire up your coding agent:

Terminal window
ony init # enrolls this machine and wires Claude Code

This is the fastest path for a single developer. See the quickstart for the full walkthrough, and the CLI reference for ony up, ony init, and ony doctor.

Self-hosting is bring-your-own for everything that costs money or touches a third party:

  • Telephony carrier (required for real calls). SignalWire, Twilio, Telnyx, or Plivo. There is no bundled number - self-host means your carrier account. See carrier setup.
  • A public domain or tunnel so the carrier can reach ${ONY_PUBLIC_BASE_URL}/webhooks/....
  • Models (optional). The voice brain is OpenAI-compatible; with no key it falls back to deterministic intent matching, so inbound voice still works. See the configuration reference.

Only ONY_SIGNING_SECRET is truly required to boot; everything else is optional and can be added from the dashboard later.

You can mix these:

  1. From the dashboard (recommended, no restart). In Settings -> Integrations, an admin adds a carrier and voice models with a built-in credential test. These are encrypted at rest (Fernet, keyed from ONY_SIGNING_SECRET) in the database and applied live. A dashboard-configured carrier takes precedence over the env value.
  2. From the environment (config-as-code). Everything can be set in .env for reproducible deployments. See .env.example and the configuration reference.

Bring your own domain: three webhook-edge options

Section titled “Bring your own domain: three webhook-edge options”

The carrier must reach ${ONY_PUBLIC_BASE_URL}/webhooks/.... Ony.ai only needs ONY_PUBLIC_BASE_URL pointed at a publicly reachable address; how you get there is your choice.

  1. Reverse proxy (Caddy / nginx / Traefik) on your own server and domain, forwarding to the Ony.ai web origin. The standard production setup.
  2. Cloudflare Tunnel. Run cloudflared next to the stack; it dials out to Cloudflare, so there are no open inbound ports. Add -f deploy/docker-compose.cloudflared.yml and set ONY_TRUST_CF_CONNECTING_IP=true. Runbook: CLOUDFLARE-TUNNEL.md.
  3. Cloudflare Worker edge. Deploy the Worker in deploy/cloudflare-worker/ on hooks.yourdomain.com; it forwards /webhooks/* (and optionally /api/*) to your origin. Good when the backend sits on a private network. When the edge is webhook-only, set ONY_WEB_BASE_URL to the host that actually serves the dashboard so user-facing links stay correct.

The deploy/ directory holds the operational guides:

  • README.md - stand the stack up.
  • RUNBOOK.md - health checks, backups, migrations, and secret rotation.
  • SCALING.md - multi-instance and DoS tuning (a shared ONY_REDIS_URL is required for cross-worker decision push).
  • BACKUP.md - nightly encrypted backups.

Work through the hardening guide (secrets and rotation, per-channel webhook auth, trusted proxy hops, TLS, and a pre-deploy checklist) and read the threat model. Risk classification is server-authoritative: a call happens only when policy permits it.

The core is AGPL-3.0. If you run a modified version as a network service, you must offer your modified source to its users. A hosted plan (no infrastructure to run) lives at ony.ai and is currently a waitlist.