Skip to main content
OpenTracy ghost holding a shield — self-host when you need full control over data residency and security Most of OpenTracy works from just pip install opentracy. You need the full self-hosted stack if you want:
  • Trace storage and analytics (ClickHouse-backed).
  • The UI at localhost:3000 for browsing traces, datasets, experiments.
  • Distillation (Distiller client — requires the REST API + a GPU).
  • Engine-side routing aliases (the model="smart" → distilled-student swap).

Prerequisites

  • Docker ≥ 24 and Docker Compose v2
  • An NVIDIA GPU + nvidia-container-toolkit if you plan to run distillation
  • ~10 GB free disk for ClickHouse + weights + training artifacts
On Linux with an NVIDIA GPU:
If that last command prints your GPU, you’re ready.

Start the stack

After a minute or two: Health-check them all:
make start-full is defined in the repo’s top-level Makefile. It pulls the pinned images, bakes a docker-compose.yml with the four services above, and waits until ClickHouse is reachable before starting the engine. Run make help to see every command.

What each service is

  • opentracy-engine (Go) — the gateway. Receives /v1/chat/completions, authenticates to upstream providers, streams responses back, writes traces to ClickHouse. Also exposes /v1/route for auto-routing.
  • opentracy-api (Python, FastAPI) — business logic on top of traces: datasets, evaluations, distillation jobs. Uses ClickHouse for reads, launches training subprocesses.
  • clickhouse — column-store for traces and analytics.
  • ui (Next.js) — the dashboard.

Configuration knobs

Provider API keys live under ~/.opentracy/secrets.json on the host (mounted into the engine container):
Or via env vars passed through to the engine:
Other env vars worth knowing (all read by the opentracy-api container):
Legacy LUNAR_* env vars still work and fall back to the new OPENTRACY_* names with a one-time DeprecationWarning. Migrate when you touch the env file — no rush.

Point your app at the local stack

Or with the OpenAI SDK — see the drop-in-openai guide.

Running distillation

With the stack up and at least one GPU visible:
If the training step fails with “HuggingFace access required”, the student model is gated — add your HuggingFace token in UI → Settings → Integrations, then retry. The engine’s trainer subprocess picks up the token from secrets storage automatically.

Updating

Migration: database schema changes are handled automatically on startup. Routing weights update whenever a newer version appears in the Hub (ot.download("weights-default") refreshes them locally).

Stopping

Data persists in volumes (clickhouse-data, weights-data, distillation-data). To wipe everything and start fresh:

Production considerations

The engine has no auth out of the box. Do not expose port 8080 publicly. Put it behind an auth proxy (Traefik, Caddy with mTLS, a VPN, etc.).
ClickHouse defaults are for dev. The compose file starts ClickHouse with the default password opentracy and no TLS. For production, set a real password (CLICKHOUSE_PASSWORD env var), enable HTTPS, and take regular backups.
Distillation artifacts are on the host. The distillation-data volume ends up under Docker’s volume root; set up regular backups if the adapters matter beyond reproducing them from the dataset.

Next

Pipeline

Understand how the self-hosted stack implements the pipeline.

Python SDK

The thin client that talks to the stack you just started.