Docker & Deployment
Run ModelTrack locally with Docker Compose, or deploy to production with individual containers.
Docker Compose (local development)
The fastest way to get started. This runs all four services locally:
terminal
git clone https://github.com/ModelTrack/modeltrack.git
cd modeltrack
docker compose upThis starts:
- →Proxy (Go) on port
8080— handles all LLM requests - →API (Node.js) on port
3001— serves dashboard data - →Collector — aggregates infrastructure metrics
- →Dashboard on port
5173— web UI
The docker-compose.yml
docker-compose.yml
services:
proxy:
build: ./proxy
ports:
- "8080:8080"
environment:
- PROXY_PORT=8080
- ANTHROPIC_BASE_URL=https://api.anthropic.com
- DATA_DIR=/data
- LOG_LEVEL=info
volumes:
- ./data:/data
api:
build: ./api
ports:
- "3001:3001"
environment:
- PORT=3001
- DATA_DIR=/data
- DB_PATH=/data/modeltrack.db
volumes:
- ./data:/data
depends_on:
- proxy
collector:
build: ./collector
environment:
- DATA_DIR=/data
- ENABLE_AWS_COSTS=false
- ENABLE_OPENCOST=false
- ENABLE_GPU_METRICS=false
volumes:
- ./data:/data
depends_on:
- api
dashboard:
build: ./dashboard
ports:
- "5173:4173"
depends_on:
- apiIndividual Docker images
Each service has its own Dockerfile. Build and run them individually:
terminal
# Build individual images
docker build -t modeltrack-proxy ./proxy
docker build -t modeltrack-api ./api
docker build -t modeltrack-collector ./collector
docker build -t modeltrack-dashboard ./dashboard
# Run the proxy standalone
docker run -d \
-p 8080:8080 \
-v $(pwd)/data:/data \
-e PROXY_PORT=8080 \
-e ANTHROPIC_BASE_URL=https://api.anthropic.com \
-e DATA_DIR=/data \
modeltrack-proxyEnvironment variables reference
Proxy
| Variable | Default | Description |
|---|---|---|
PROXY_PORT | 8080 | Proxy listen port |
ANTHROPIC_BASE_URL | https://api.anthropic.com | Upstream Anthropic API |
OPENAI_BASE_URL | https://api.openai.com | Upstream OpenAI API |
DATA_DIR | ../data | Directory for cost events and config files |
LOG_LEVEL | info | Logging verbosity |
CACHE_ENABLED | true | Enable response caching |
CACHE_TTL_SECONDS | 3600 | Cache entry time-to-live |
API
| Variable | Default | Description |
|---|---|---|
PORT | 3001 | API listen port |
DATA_DIR | /data | Directory for cost events and config files |
DB_PATH | /data/modeltrack.db | SQLite database path |
SLACK_WEBHOOK_URL | - | Slack webhook for alerts and reports |
Collector
| Variable | Default | Description |
|---|---|---|
DATA_DIR | /data | Directory for cost events |
ENABLE_AWS_COSTS | false | Enable AWS Cost Explorer integration |
ENABLE_OPENCOST | false | Enable OpenCost integration |
ENABLE_GPU_METRICS | false | Enable GPU metrics collection |
Running in production
When deploying ModelTrack to production, consider the following:
- Persistence: The
data/directory contains cost events (JSONL), the SQLite database, and config files (budgets, routing rules). Mount this to a persistent volume. - Networking: The proxy should be accessible from your application pods but not from the public internet. Deploy it within your VPC or internal network.
- Scaling: The proxy is stateless (except for the in-memory cache). You can run multiple proxy instances behind a load balancer. The API service writes to SQLite, so run a single API instance or switch to PostgreSQL for multi-instance setups.
- Health checks: The proxy exposes
GET /healthzfor liveness probes.
Kubernetes
Here is a minimal Kubernetes deployment for the proxy. Adapt as needed for your cluster.
modeltrack-proxy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: modeltrack-proxy
labels:
app: modeltrack-proxy
spec:
replicas: 2
selector:
matchLabels:
app: modeltrack-proxy
template:
metadata:
labels:
app: modeltrack-proxy
spec:
containers:
- name: proxy
image: modeltrack-proxy:latest
ports:
- containerPort: 8080
env:
- name: PROXY_PORT
value: "8080"
- name: ANTHROPIC_BASE_URL
value: "https://api.anthropic.com"
- name: DATA_DIR
value: "/data"
- name: CACHE_ENABLED
value: "true"
volumeMounts:
- name: data
mountPath: /data
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: data
persistentVolumeClaim:
claimName: modeltrack-data
---
apiVersion: v1
kind: Service
metadata:
name: modeltrack-proxy
spec:
selector:
app: modeltrack-proxy
ports:
- port: 8080
targetPort: 8080
type: ClusterIPNote: A full Helm chart is planned for a future release. For now, use these manifests as a starting point and customize for your environment.