---
title: "Deploy OmniRoute"
description: "Open-source LLM gateway: routing, fallbacks, API keys, cost analytics"
category: "Other"
url: https://railway.com/deploy/omni-route
---

# Deploy OmniRoute

Open-source LLM gateway: routing, fallbacks, API keys, cost analytics

**[Deploy OmniRoute on Railway](https://railway.com/template/omni-route)**

- **Creator:** A3A
- **Category:** Other
- **Total deploys:** 56

## Template content

### omniroute

- **Image:** diegosouzapw/omniroute
- **Public domain:** Yes

## Documentation

![OmniRoute logo](https://github.com/diegosouzapw/OmniRoute/raw/release/v3.8.50/docs/diagrams/readme-hero.svg)

# Deploy and Host OmniRoute on Railway

OmniRoute is an open-source AI gateway that puts one OpenAI-compatible `/v1` endpoint in front of every model provider you use. Rather than scattering API keys, base URLs, retry logic, and spend tracking across each application, you connect your own provider credentials once and point every client at a single address. A Next.js dashboard sits on a routing engine handling provider selection, failover chains, format translation, prompt compression, rate limiting, and cost analytics. Self-host OmniRoute to keep credentials on infrastructure you control.

This template runs one Railway service, `omniroute`, from the official image `diegosouzapw/omniroute:3.8.48`. There is no database container — all state lives in SQLite, so a volume is mounted at `/app/data` with `DATA_DIR` set to match. HTTPS terminates at the Railway edge and forwards to port `20128`, which serves `/login` and `/dashboard` for the UI and `/v1/*` for API traffic.

![OmniRoute Railway architecture](https://res.cloudinary.com/rroe4rtk/image/upload/v1785648220/300_1x_shots_so_yze0wb.png)

## Getting Started with OmniRoute on Railway

Open the generated Railway domain; every unauthenticated path redirects to `/login`. OmniRoute is gated by one dashboard password rather than user accounts, so sign in with the generated `INITIAL_PASSWORD` from the Variables tab, then change it under Configuration → Security. A fresh gateway has **no providers connected**, so the first real step is Dashboard → Providers → add a provider and paste your own API key; this is a bring-your-own-key gateway and ships no credentials. Then open API Keys and issue a gateway key, since `REQUIRE_API_KEY` is `true` and every `/v1` call must present one. Confirm the Endpoints page shows `https:///v1`, not `localhost`, then verify with `/v1/models` — it returns your models with a valid key and `401` without — and point any OpenAI SDK at that base URL.

![OmniRoute dashboard screenshot](https://res.cloudinary.com/rroe4rtk/image/upload/v1785647666/38_1x_shots_so_fdcmxj.png)

## About Hosting OmniRoute

Every model vendor brings its own SDK, auth scheme, error shape, rate limit, and billing portal, and that cost compounds the moment a codebase talks to more than one. Self-hosting fits when credentials must not leave your perimeter, when a team wants one shared endpoint with revocable per-client keys, or when you need routing policy hosted aggregators do not expose.

- **OpenAI-compatible `/v1` API** — chat completions, model listing, and the Responses API, with format translation between provider shapes.
- **Routing strategies and fallback combos** — priority, weighted, round-robin, cost-optimised; combos chain providers so a failing upstream hands the request onward.
- **Scoped keys, compression, and analytics** — per-app keys you revoke without touching provider credentials, token trimming on long agent sessions, and per-provider cost and latency.

## Why Deploy OmniRoute on Railway

Railway removes the plumbing around a self-hosted gateway.

- One-click deploy from the pinned `diegosouzapw/omniroute:3.8.48` image.
- A volume at `/app/data` keeps SQLite state across restarts and redeploys.
- Free HTTPS domain with automatic TLS, so `/v1` is reachable immediately.
- Usage-based pricing — pay for the CPU and RAM the gateway uses.
- Built-in logs, metrics, and one-click rollbacks.

## Common Use Cases of OmniRoute

- **A shared team gateway for coding agents.** Point Claude Code, Codex CLI, Cursor, and Cline at one `/v1` URL and rotate a vendor credential in one place, not a dozen editor configs.
- **Multi-provider resilience.** A fallback combo behind one model alias fails over to your secondary vendor instead of surfacing an outage.
- **A stable endpoint in front of changing models.** Apps call one base URL while the dashboard attributes token spend by provider, key, and application.

## Dependencies for OmniRoute

- **`omniroute`** — `diegosouzapw/omniroute:3.8.48`, the official multi-arch (amd64/arm64) image. Dashboard and routing engine in one Node.js process on port `20128`; the domain's target port must match or requests never reach the app.
- **Volume at `/app/data`** — `storage.sqlite`, `db_backups/` (written before each migration), and `logs/`. First boot writes about 90 MB.

Two image lines ship per release: the base tag used here (`3.8.48`, ~460 MB) and `-web` (~915 MB), which only adds Chromium for browser-session providers. Pin a semver tag — `latest` and `main` move.

### OmniRoute Environment Variables Reference

| Variable | Value | What it does |
|---|---|---|
| `PORT` | `20128` | Must match the domain's target port |
| `DATA_DIR` | `/app/data` | Points SQLite, backups, logs at the volume |
| `RAILWAY_RUN_UID` | `0` | Lets the process write to the volume |
| `REQUIRE_API_KEY` | `true` | Rejects unauthenticated `/v1` (default `false`) |
| `INITIAL_PASSWORD` | generated | Bootstrap password; change after login |
| `JWT_SECRET` / `API_KEY_SECRET` | generated | Sign sessions, encrypt keys; keep stable |
| `OMNIROUTE_MEMORY_MB` | `2048` | V8 heap ceiling in MB |
| `BASE_URL` / `NEXT_PUBLIC_BASE_URL` | `https://${{RAILWAY_PUBLIC_DOMAIN}}` | Canonical public URLs |
| `STORAGE_ENCRYPTION_KEY` | unset | Full-DB encryption; set before first boot only |

### Deployment Dependencies

- [`diegosouzapw/omniroute`](https://hub.docker.com/r/diegosouzapw/omniroute) — repo [github.com/diegosouzapw/OmniRoute](https://github.com/diegosouzapw/OmniRoute) (MIT)
- Node.js 22+ bundled; SQLite via `better-sqlite3`

## Hardware Requirements for Self-Hosting OmniRoute

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.5 vCPU | 1–2 vCPU |
| RAM | 1 GB | 2–4 GB |
| Storage | 2 GB volume | 5 GB volume |
| Runtime | Node.js 22+ (bundled) | Node.js 22+ (bundled) |

Proxying is I/O-bound, so memory matters more than CPU. Set `OMNIROUTE_MEMORY_MB` to about half the container's limit — Node otherwise sizes its heap from the host's RAM, not the container's, and gets OOM-killed under load.

## Self-Hosting OmniRoute with Docker

The same setup runs anywhere Docker does:

```
docker run -d --name omniroute --restart unless-stopped \
  --stop-timeout 40 -p 20128:20128 -v omniroute-data:/app/data \
  -e DATA_DIR=/app/data -e HOSTNAME=0.0.0.0 \
  -e NODE_ENV=production -e REQUIRE_API_KEY=true \
  -e INITIAL_PASSWORD="change-me-on-first-login" \
  -e JWT_SECRET="$(openssl rand -base64 48)" \
  -e API_KEY_SECRET="$(openssl rand -hex 32)" \
  diegosouzapw/omniroute:3.8.48
```

Keep the 40-second stop timeout — OmniRoute checkpoints SQLite on shutdown, and killing it early drops recent writes. Then confirm it answers:

```
curl -s https://your-app.up.railway.app/v1/chat/completions \
  -H "Authorization: Bearer YOUR_GATEWAY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"auto","messages":[{"role":"user","content":"ping"}]}'
```

## How Much Does OmniRoute Cost to Self-Host?

OmniRoute is free and MIT-licensed — no paid tier, seat charge, or per-request fee. Your real costs are the infrastructure it runs on and whatever your providers charge for the tokens you send; the gateway routes with your own API keys and never bills for inference. On Railway you pay usage-based pricing for CPU, memory, egress, and the volume — typically a few dollars a month for a small team.

## Troubleshooting Self-Hosted OmniRoute on Railway

- **State resets on every restart.** The container could not write to the volume, so the app silently fell back to an in-memory database while still serving HTTP 200. Fix: set `RAILWAY_RUN_UID=0`, redeploy, then confirm a gateway key survives a restart — a green deploy is not proof of persistence.
- **Keys or sessions break after redeploy.** `JWT_SECRET` or `API_KEY_SECRET` changed; both must stay fixed.

## FAQ

**What is OmniRoute?**

An open-source, MIT-licensed AI gateway exposing one OpenAI-compatible `/v1` endpoint that routes to the providers you connect with your own API keys, plus a dashboard for routing rules, scoped keys, compression, and analytics.

**What does this Railway template deploy?**

One `omniroute` service from `diegosouzapw/omniroute:3.8.48` on port `20128`, with a volume at `/app/data`. Secrets are generated at deploy time, `REQUIRE_API_KEY` is `true`, and `BASE_URL` points at your Railway domain.

**Why does this template use a volume instead of a Postgres database?**

All state lives in a SQLite file under `DATA_DIR`, and this image has no Postgres driver path, so a managed database would add cost without being used.

**How do I connect Claude Code, Cursor, or an OpenAI SDK to self-hosted OmniRoute?**

Set the client's base URL to `https:///v1` and its API key to a gateway key from the API Keys page. Any tool accepting a custom base URL works.

**Do I need to bring my own provider API keys?**

Yes. The gateway ships with no credentials and no providers connected, so `/v1/chat/completions` cannot route anything until you add a provider with your own key.

## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — [Jul'26] Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/omni-route
