DodoRouter
Get Started
Docs / Self-hosting
Browse docs
View as Markdown

Self-hosting

DodoRouter is a standard Phoenix 1.8 application backed by PostgreSQL. Source: github.com/foxwise-ai/dodorouter. License terms are covered in License below — in short, free to self-host and modify, but you can't resell it as your own competing hosted service.

Prerequisites

  • Elixir 1.15+ and a matching Erlang/OTP
  • PostgreSQL 12+
  • An Infisical project (free tier is fine) — see the callout below, this is currently required, not optional

⚠ Infisical is currently required

Every provider API key you add (OpenAI, Anthropic, z.ai, …) is stored via Infisical, a secrets manager — there is currently no local/plaintext fallback in the code. Without INFISICAL_TOKEN and INFISICAL_PROJECT_ID set, the app boots fine and the dashboard loads, but clicking Add Key on the Providers page will fail with "Failed to store API key securely" — so you won't be able to configure any provider, and no requests will succeed. Sign up at Infisical, create a project, create a Machine Identity with a Universal Auth client, and use that identity's access token as INFISICAL_TOKEN.

1. Clone and install

git clone https://github.com/foxwise-ai/dodorouter.git
cd dodorouter
mix deps.get

2. Configure environment variables

For local development, export these before starting the server (e.g. in .envrc with direnv, or a .env you source):

# Database — defaults match config/dev.exs; override if yours differs
export DB_USERNAME=postgres
export DB_PASSWORD=postgres
export DB_HOSTNAME=localhost
export DB_PORT=5432
export DB_NAME=dodo_router_dev

# Infisical — required, see callout above
export INFISICAL_TOKEN="<your machine identity access token>"
export INFISICAL_PROJECT_ID="<your infisical project id>"
export INFISICAL_ENVIRONMENT=dev   # optional, defaults to "prod"

3. Set up the database

mix ecto.setup

4. Start the server

mix phx.server

Visit http://localhost:4000. Register an account, confirm via the magic-link email — in dev, DodoRouter uses Swoosh's local mailbox instead of sending real email, so open http://localhost:4000/dev/mailbox to read it. From there, follow the same steps as the Quickstart.

Verified: GET /health returns {"status":"ok"} once the DB connection is healthy, and GET /api/version returns the running app version, e.g. {"version":"0.1.75"} — handy for confirming the app booted and for health-check probes.

Production environment variables

Variable Required Notes
DATABASE_URL Yes e.g. ecto://user:pass@host/dodo_router_prod
SECRET_KEY_BASE Yes Generate with mix phx.gen.secret
PHX_HOST Yes Your public domain
PHX_SERVER Yes Set to true to actually start the endpoint under a release
PORT No Defaults to 4000
INFISICAL_TOKEN Yes* *Required for provider-key storage to work at all (see callout above)
INFISICAL_PROJECT_ID Yes* Paired with the token above
INFISICAL_ENVIRONMENT No Defaults to prod
RESEND_API_KEY No Transactional email (magic links). Without it in prod, mail simply won't send
EMAIL_FROM No Defaults to noreply@dodorouter.com
STRIPE_SECRET_KEY No Only set this if you want the $19/mo billing paywall enabled. Unset = billing disabled, everyone has full access
STRIPE_WEBHOOK_SECRET No Required only alongside STRIPE_SECRET_KEY
ECTO_IPV6 No Set to true to enable IPv6 for the DB socket
POOL_SIZE No Ecto pool size, defaults to 10

For deploy specifics (hot code upgrades, systemd, Castle release management), see the project's own AGENTS.md in the repo — those are maintainer-facing operational details rather than user-facing setup, so we won't duplicate them here. See also Deployment for a minimal production boot sequence.

License

DodoRouter is source-available under the O'Saasy License. In short: you're free to use, modify, self-host, and even sell copies of it — the one thing you can't do is turn around and offer it as a competing hosted/managed service where the software itself is the product. See the full license text in the repository for the exact terms.