Self-hosted LLM gateway in Rust: OpenAI-compatible API, virtual keys, budgets and spend per team
437
A self-hosted LLM gateway in one Rust binary. Point any OpenAI SDK at it, hand each team a virtual key, and see exactly what every one of them spent.
OpenAI- and Anthropic-compatible API in front of OpenAI, Azure OpenAI, Anthropic, Google Gemini, Groq, Mistral, DeepSeek, OpenRouter, Together, Ollama or any OpenAI-compatible server. The dashboard is inside the same image.
amd64 and arm64, distroless, runs as non-rootx-litellm-* headers, litellm_metadata,
LITELLM_MASTER_KEY and router_settings| Tag | Database | Use it for |
|---|---|---|
latest, vX.Y.Z | SQLite | one container, nothing to provision |
postgres, vX.Y.Z-postgres | PostgreSQL | an existing Postgres, larger installs |
Pin a version (v0.1.0) in production; latest moves with every release.
docker run -d --name llmtrack -p 4000:4000 -v llmtrack_data:/data \
-e SECRET_KEY=$(openssl rand -hex 32) \
-e [email protected]:changeme123 \
rustrak/llmtrack:latest
Open http://localhost:4000, sign in, add a model, create a team and a key. Then call it like OpenAI:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4000/v1", api_key="sk-…")
client.chat.completions.create(
model="gpt-5.6",
messages=[{"role": "user", "content": "Hello"}],
)
services:
llmtrack:
image: rustrak/llmtrack:latest
ports: ["4000:4000"]
volumes: [llmtrack_data:/data]
environment:
- SECRET_KEY=${SECRET_KEY}
- CREATE_SUPERUSER=${CREATE_SUPERUSER}
restart: unless-stopped
volumes:
llmtrack_data:
services:
llmtrack:
image: rustrak/llmtrack:postgres
ports: ["4000:4000"]
environment:
- DATABASE_URL=postgres://llmtrack:llmtrack@db:5432/llmtrack
- SECRET_KEY=${SECRET_KEY}
- CREATE_SUPERUSER=${CREATE_SUPERUSER}
depends_on: [db]
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=llmtrack
- POSTGRES_PASSWORD=llmtrack
- POSTGRES_DB=llmtrack
volumes: [pg_data:/var/lib/postgresql/data]
volumes:
pg_data:
| Variable | Required | What it does |
|---|---|---|
SECRET_KEY | yes | At least 64 characters (openssl rand -hex 32). Signs the session and encrypts the stored provider keys: changing it makes them unreadable |
CREATE_SUPERUSER | no | email:password, the first admin, created only into an empty database |
DATABASE_URL | no | Default sqlite:///data/llmtrack.db. postgres://… on the :postgres image |
MASTER_KEY | no | sk-… bearer token for the management API, for scripts and CI. LITELLM_MASTER_KEY is read too |
PORT | no | Default 4000 |
SSL_PROXY | no | true behind a TLS-terminating proxy: secure cookies |
UPSTREAM_TIMEOUT_SECS | no | How long to wait on a silent provider, per read. Default 600 |
LLMTRACK_DASHBOARD | no | off serves the API only |
RUST_LOG | no | info, debug, warn, error |
Data lives in the /data volume. Back it up; it holds your keys, settings
and usage history.
License: GPL-3.0.
Content type
Image
Digest
sha256:08a2fbf23…
Size
16.9 MB
Last updated
about 15 hours ago
docker pull rustrak/llmtrack