How to run obleth, the mock backend, and the control-plane dashboard locally outside Docker for fast iteration.
Running outside Docker gives you faster rebuild cycles and easier debugger attachment. You still need Redis, Postgres, and ClickHouse running somewhere — the easiest approach is to start only the datastores from Compose while running the application code natively.
cd obleth-gateway
# Start Postgres, Redis, ClickHouse only (no application services)
docker compose -f deploy/docker/docker-compose.yml \
up postgres redis clickhouse -d
Wait for healthchecks to pass:
docker compose -f deploy/docker/docker-compose.yml ps
# All three should show "healthy"
The mock backend is a Node.js OpenAI-compatible server that simulates TTFT and token streaming without a GPU:
cd obleth-gateway
node mock-backend/server.mjs
# Listening on :8081
cd obleth-gateway/obleth
cargo run --release 2>&1 | tee obleth.log
With the right environment:
# PowerShell
$env:OBLETH_DATABASE_URL = "postgres://obleth:obleth@localhost:5432/obleth"
$env:OBLETH_REDIS_URL = "redis://localhost:6379"
$env:OBLETH_CLICKHOUSE_URL = "http://localhost:8123"
$env:OBLETH_UPSTREAM_BASE_URL = "http://localhost:8081"
$env:OBLETH_ADMIN_TOKEN = "dev-admin-token"
$env:OBLETH_FAIL_OPEN = "true"
$env:OBLETH_FAIRSHARE_ALGORITHM = "hierarchical"
$env:RUST_LOG = "obleth=debug,info"
cargo run
# Bash
export OBLETH_DATABASE_URL=postgres://obleth:obleth@localhost:5432/obleth
export OBLETH_REDIS_URL=redis://localhost:6379
export OBLETH_CLICKHOUSE_URL=http://localhost:8123
export OBLETH_UPSTREAM_BASE_URL=http://localhost:8081
export OBLETH_ADMIN_TOKEN=dev-admin-token
export OBLETH_FAIL_OPEN=true
export RUST_LOG=obleth=debug,info
cargo run
obleth applies its embedded schema on first boot. After a few seconds you should see:
INFO obleth_proxy: postgres connected + schema applied
INFO obleth_proxy: redis connected
INFO obleth_proxy: clickhouse connected + schema applied
INFO obleth_proxy: warmed key cache count=0
INFO obleth_proxy: listening: proxy=0.0.0.0:8080, admin=0.0.0.0:9090, metrics=0.0.0.0:9091
cd obleth-gateway/control-plane
cp .env.example .env
# Edit .env: set OBLETH_ADMIN_BASE_URL=http://localhost:9090
npm install
npm run dev
# Dashboard available at http://localhost:3000
# Create a tenant
TID=$(curl -s -X POST http://localhost:9090/api/v1/tenants \
-H "Authorization: Bearer dev-admin-token" \
-H "Content-Type: application/json" \
-d '{"name":"dev","weight":100,"tokens_per_minute":100000}' | jq -r .id)
# Mint a key
SECRET=$(curl -s -X POST "http://localhost:9090/api/v1/tenants/$TID/keys" \
-H "Authorization: Bearer dev-admin-token" \
-H "Content-Type: application/json" \
-d '{"name":"local"}' | jq -r .secret)
# Call the data plane
curl -s http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer $SECRET" \
-H "Content-Type: application/json" \
-d '{"model":"mock-model","messages":[{"role":"user","content":"hi"}],"max_tokens":16}'
| Variable | Dev default | Notes |
|---|---|---|
RUST_LOG | info | Set to obleth=debug,info for verbose data plane tracing |
OBLETH_BROWNOUT_WAIT_MS | 750 | Lower (e.g. 100) to see brownout in tests faster |
OBLETH_GLOBAL_MAX_IN_FLIGHT | 256 | Lower (e.g. 4) to force queue saturation in tests |
OBLETH_FAIRSHARE_ALGORITHM | hierarchical | Switch to weighted to test flat scheduling |
OBLETH_FAIL_OPEN | true | Set false to test fail-closed behavior |
OBLETH_OTEL_ENDPOINT | (unset) | Set to http://localhost:4318 if you run Jaeger locally |
cd obleth-gateway/obleth
cargo test
Tests are mostly unit tests on the fairshare algorithm, Redis scripts, and tokenizer. Integration tests require the datastores to be running.