Перейти к содержимому
OmniRoute source

🚀 Self-Host Guide — OmniRoute (零月费自托管 / zero-fee self-host)

TL;DR — three commands, one local endpoint, zero monthly fees. No SaaS billing, no multi-tenant isolation, no hosted prompt-processing hop. Your prompts go straight to the provider you pick.

Окно терминала
cp .env.selfhost.example .env # then edit the 2 lines marked "EDIT ME"
docker compose -f docker-compose.selfhost.yml up -d
open http://127.0.0.1:20128

This is the self-host carrier for OmniRoute’s “零月费 + 自托管” product form: a packaged container/binary you run on your own machine in 5 minutes.


OmniRoute ships a sophisticated docker-compose.yml with profiles (base, web, cli, host, cliproxyapi, memory, bifrost). Each app service is profile-gated, so a bare docker compose up -d only starts Redis. That is correct for power users who pick a profile — but it is not a 5-minute self-host story.

docker-compose.selfhost.yml is the KISS overlay: one command, published image, loopback-only, Redis included, no profile choice, no build step. When you outgrow it, graduate to the full DOCKER_GUIDE profiles.

Audience Start here Graduate to
Self-hoster, single user this guide —
Power user, CLI tools / web-cookie providers / sidecars — docker-compose.yml profiles

  • Docker Engine 24+ (or Docker Desktop 4.30+) with the Compose v2 plugin.
  • ~2 GB RAM free (see Sizing).
  • A provider API key from any supported provider (OpenAI, Anthropic, Google, or one of the 150+ free tiers).

No build toolchain, no Node, no git clone required — the image is pulled.


Окно терминала
cp .env.selfhost.example .env

Edit exactly two lines in .env:

REQUIRE_API_KEY=true # was false — lock the endpoint down
APP_BIND_HOST=127.0.0.1 # keep loopback; see "Exposing" only if needed

REQUIRE_API_KEY=true makes every /v1 request and the dashboard require an API key / login. On first boot the dashboard auto-generates an INITIAL_PASSWORD — read it from the logs:

Окно терминала
docker logs omniroute | grep -i password

The other variables (DASHBOARD_PORT, API_PORT, LIVE_WS_PORT, OMNIROUTE_MEMORY_MB) already have sane defaults. Leave them unless you know you need to change them.


Окно терминала
docker compose -f docker-compose.selfhost.yml up -d

Pulls diegosouzapw/omniroute:latest (multi-arch AMD64 + ARM64, ~250 MB) and redis:8.6.5-alpine, starts both, and waits for Redis to be healthy before the app boots.

Окно терминала
# process lifecycle + readiness
curl -fsS http://127.0.0.1:20128/healthz && echo
# container health
docker inspect --format '{{.State.Health.Status}}' omniroute

You should see {"status":"ok"} and healthy. Then open the dashboard:

http://127.0.0.1:20128

Within ~300 s of up -d the endpoint is locally reachable and the healthcheck is healthy — the acceptance bar from the self-host issue.


Port What Default bind
20128 Dashboard + /v1 LLM proxy (unified entry) 127.0.0.1
20129 API port (server-to-server) 127.0.0.1
20132 Live WebSocket (realtime dashboard updates) 127.0.0.1

All three bind to loopback only by default. Redis is not published to the host at all — the app reaches it over the compose network. This is deliberate: shipping an unauthenticated Redis on 0.0.0.0 is a footgun.


  1. Open the dashboard → Providers.
  2. Add a provider and paste its API key. Keys are encrypted at rest with AES-256-GCM; the cleartext never leaves your machine.
  3. Point your IDE / agent at the unified entry:
http://127.0.0.1:20128/v1

For provider choice, see the Free Tiers Guide — OmniRoute aggregates 150+ free tiers into one endpoint, so you can run model: "auto" to pick the best free option per request.


The image pins OMNIROUTE_MEMORY_MB=1024. That is enough for the dashboard and light chat. Coding agents (POST /v1/responses from Claude Code, Codex, Grok, …) retain multiple large context graphs during compression and can abort V8 at ~12 GiB old-space under two overlapping long contexts (#7849).

.env.selfhost.example defaults to OMNIROUTE_MEMORY_MB=2048 — a safe floor for a single user running coding agents. Raise it if you fan out many models in parallel (fusion combos) or hit FATAL ERROR: Reached heap limit:

OMNIROUTE_MEMORY_MB=4096

Memory is a V8 heap ceiling; native buffers (SQLite, ONNX, better-sqlite3) sit outside it, so size the container a few hundred MB above the heap.


Prefer a binary over Docker? The npm package is the same code:

Окно терминала
npm install -g omniroute
omniroute

This runs the Next.js standalone server directly on your host — same ports, same DATA_DIR (./data by default). Use it when you cannot run Docker (e.g. a locked-down VM). The container path above is the recommended default because it bundles the exact runtime the image was tested with.

From source (development only — not a deploy path):

Окно терминала
git clone https://github.com/diegosouzapw/OmniRoute.git
cd OmniRoute
npm install
npm run build && npm start

Do not flip APP_BIND_HOST=0.0.0.0 while REQUIRE_API_KEY=false. That publishes an open /v1 proxy on every LAN/WAN interface — anyone on the network can burn your provider quotas. The order is fixed:

  1. Set REQUIRE_API_KEY=true in .env.
  2. Read INITIAL_PASSWORD from the logs and log in.
  3. Only then set APP_BIND_HOST=0.0.0.0 (or put an auth-enforcing reverse proxy in front and keep loopback).

For TLS / a domain, run Caddy or Traefik in front and leave APP_BIND_HOST at 127.0.0.1. See the DOCKER_GUIDE — Caddy HTTPS and Cloudflare Quick Tunnel sections for copy-paste reverse-proxy configs.


  • Data dir: ./data (bind-mounted to /app/data). All SQLite DBs, migrations, audit trail, and encrypted provider keys live here.
  • Backups: SQLite auto-backup is on by default (DISABLE_SQLITE_AUTO_BACKUP is unset → enabled). For a manual snapshot:
    Окно терминала
    ./bin/snapshot-data.sh
    Restore with ./bin/restore-data.sh.
  • Reset the dashboard password:
    Окно терминала
    docker exec -it omniroute node bin/reset-password.mjs
  • Reset policies (routing/failover/quota to factory defaults):
    Окно терминала
    docker exec -it omniroute node bin/restore-policies.sh

docker compose up only starts Redis

You are running the full docker-compose.yml, whose app services are profile-gated. For the one-command path use the self-host file:

Окно терминала
docker compose -f docker-compose.selfhost.yml up -d

Or, with the full compose, pick a profile: docker compose --profile base up -d.

Healthcheck stays starting / unhealthy
  • Check Redis is up: docker inspect --format '{{.State.Health.Status}}' omniroute-redis
  • Check app logs: docker logs omniroute
  • The healthcheck probes /healthz and allows a 20 s start period. A slow first boot (cold migrations) can take longer — bump start_period in the compose file if your disk is slow.
FATAL ERROR: Reached heap limit under coding agents

Raise OMNIROUTE_MEMORY_MB in .env (e.g. 4096), then docker compose -f docker-compose.selfhost.yml up -d. See Sizing the container.

Web-cookie providers (Gemini Web, Claude Turnstile) fail with Executable doesn't exist at .../ms-playwright/chromium

The base image ships without Chromium. The self-host compose uses the published base image. For web-cookie providers, switch to the full compose with the web profile (which bundles Playwright/Chromium):

Окно терминала
docker compose --profile web up -d

See DOCKER_GUIDE — Available Profiles.

Port 20128 already in use

Set DASHBOARD_PORT, API_PORT, LIVE_WS_PORT in .env to free ports and re-run up -d.


Per the self-host KISS constraint, this path does not include:

  • ❌ SaaS billing / metering / plan tiers
  • ❌ Multi-tenant isolation / per-tenant namespaces
  • ❌ A hosted prompt-processing hop (your prompts go straight to the provider)
  • ❌ Any baked-in credentials or secrets

It is a pure local self-host carrier — the simplest thing that makes the “零月费 + 自托管” promise real.


Before you expose beyond loopback:

  • REQUIRE_API_KEY=true in .env
  • INITIAL_PASSWORD rotated to a strong, unique value
  • APP_BIND_HOST left at 127.0.0.1 unless behind an auth-enforcing proxy
  • TLS terminated by Caddy/Traefik/Cloudflare in front (never plain HTTP on WAN)
  • Redis not published to the host (the self-host compose already enforces this)
  • ./data volume backed up regularly (bin/snapshot-data.sh)
  • Provider keys rotated per the provider’s own policy

For the full supply-chain / image / dependency audit dimension, see SECURITY.md and SUPPLY_CHAIN.



Исходный код OmniRoute (a58000c7685f)

HagiCode

HagiCode — агентная среда разработки со структурированными процессами, параллельным выполнением несколькими агентами и интерфейсами Hero Dungeon.

Превращайте идеи в полезное ПО с более умным, быстрым и увлекательным агентным рабочим процессом.

Главный экран HagiCode в светлой теме
  • SmartСтруктурированные процессы превращают намерение в исполнимый путь от идеи до готового изменения.
  • EfficientМультиагентные процессы параллельно продвигают исследование, реализацию и проверку.
  • FunHero Dungeon делает длительную совместную разработку наглядной и увлекательной.
Перейти на HagiCode