version: "3.8" services: redis: image: redis:7-alpine container_name: harness-redis restart: unless-stopped ports: - "127.0.0.1:6379:6379" volumes: - redis-data:/data command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 postgres: image: postgres:16-alpine container_name: harness-postgres restart: unless-stopped ports: - "127.0.0.1:5432:5432" environment: - POSTGRES_DB=litellm - POSTGRES_USER=litellm - POSTGRES_PASSWORD=d9fc143e3dc1a7a8e672c359fea95c5e volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U litellm"] interval: 5s timeout: 3s retries: 5 router: build: ./router container_name: harness-router restart: unless-stopped ports: - "127.0.0.1:9000:9000" environment: - REDIS_URL=redis://redis:6379 - GPU_MOE_URL=http://192.168.68.15:8080/v1 - GPU_DENSE_URL=http://192.168.68.8:8080/v1 - GPU_LIGHT_URL=http://192.168.68.110:8080/v1 - API_KEYS={"sk-syslog-local-master-key":{"tier":"enterprise","agent":"admin","deprecated":true},"sk-9e65b69a67-e54af421c1b09fb8bd4f75dacb38cb64":{"tier":"enterprise","agent":"admin"},"sk-syslog-abiba":{"tier":"enterprise","agent":"Abiba","deprecated":true},"sk-856ffb0bbb-e5aaf78b10054eca608f8fbcbd73a889":{"tier":"enterprise","agent":"Abiba"},"sk-syslog-mumuni":{"tier":"enterprise","agent":"Mumuni","deprecated":true},"sk-b57e6e042e-47573660114f3138c852c47f62da807e":{"tier":"enterprise","agent":"Mumuni"},"sk-syslog-tanko":{"tier":"enterprise","agent":"Tanko","deprecated":true},"sk-620a05e95a-e93d875476b650a4d1137249ead8eaa7":{"tier":"enterprise","agent":"Tanko"},"sk-syslog-koby":{"tier":"enterprise","agent":"Koby","deprecated":true},"sk-eb3e6fc1c0-de1bf2edf35a53cb3749a2400483fdee":{"tier":"enterprise","agent":"Koby"},"sk-syslog-kagenz0":{"tier":"enterprise","agent":"Kagenz0","deprecated":true},"sk-12b66b3392-b548aed9138aeb6f698e8e521650ed9b":{"tier":"enterprise","agent":"Kagenz0"},"sk-syslog-koonimo":{"tier":"enterprise","agent":"Koonimo","deprecated":true},"sk-680d06686c-00ee8bf9dc3c93b276af122d49a14dfe":{"tier":"enterprise","agent":"Koonimo"},"sk-starter-abc123":{"tier":"starter","agent":"test-starter","deprecated":true},"sk-55da55907a-1bd7ff344e26feda50e9ac2219697860":{"tier":"starter","agent":"test-starter"},"sk-professional-xyz789":{"tier":"professional","agent":"test-pro","deprecated":true},"sk-b5159863e6-8df3ae52fb958cfe76cc2888c8c8e676":{"tier":"professional","agent":"test-pro"}} - ADMIN_KEY=sk-admin-ee09fffd04978b61a1569ac670c68814 healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9000/health')"] interval: 30s timeout: 15s retries: 3 depends_on: redis: condition: service_healthy litellm: image: docker.litellm.ai/berriai/litellm:1.90.0-rc.1 command: ["--config", "/app/config.yaml", "--port", "4000"] container_name: harness-litellm restart: unless-stopped ports: - "4001:4000" volumes: - ./litellm_config.yaml:/app/config.yaml - /opt/combined-ca-bundle.pem:/etc/ssl/certs/ca-certificates.crt:ro environment: - LITELLM_MASTER_KEY=sk-litellm-7f96080dd99b15c36bd4b333b58a6796 - ROUTER_API_KEY=sk-9e65b69a67-e54af421c1b09fb8bd4f75dacb38cb64 - DATABASE_URL=postgresql://litellm:d9fc143e3dc1a7a8e672c359fea95c5e@postgres:5432/litellm - STORE_MODEL_IN_DB=True - LITELLM_UI_USERNAME=admin - LITELLM_UI_PASSWORD=syslog-admin-2026 - UI_USERNAME=admin - UI_PASSWORD=syslog-admin-2026 - OPENAI_API_KEY=not-used - PROXY_BASE_URL=https://litellm.sysloggh.net - DOCS_URL=/docs - ANTHROPIC_API_KEY=not-used - GENERIC_CLIENT_ID=FHd7bs9dP5gHad2Ki23iUL5kQvFa0GRaj3nlLnNU - GENERIC_CLIENT_SECRET=aDkXQx82duqpxc98xxqp0quzzUf1mawsnOTqj7sx1acaS7rWSt02N5ksBCi92n8ZilRavigoYME6fLakP20Ixc9H2pxnSZFiOqQLb7BPi8UtsvfxmzXklD0HJIdbKFxe - GENERIC_AUTHORIZATION_ENDPOINT=https://auth.sysloggh.net/application/o/authorize/ - GENERIC_TOKEN_ENDPOINT=http://harness-nginx/application/o/token/ - GENERIC_USERINFO_ENDPOINT=http://harness-nginx/application/o/userinfo/ - GENERIC_SCOPE=openid email profile - GENERIC_ROLE_MAPPINGS_DEFAULT_ROLE=proxy_admin - SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt extra_hosts: - "host.docker.internal:host-gateway" - "auth.sysloggh.net:192.168.68.11" healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')"] interval: 15s timeout: 5s retries: 3 depends_on: postgres: condition: service_healthy redis: condition: service_healthy nginx: image: nginx:alpine container_name: harness-nginx restart: unless-stopped ports: - "80:80" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./dashboard:/opt/inference-harness/dashboard:ro extra_hosts: - "auth.sysloggh.net:192.168.68.11" healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1/health"] interval: 30s timeout: 15s retries: 3 depends_on: - litellm - dashboard dashboard: build: ./dashboard container_name: harness-dashboard restart: unless-stopped ports: - "127.0.0.1:3000:3000" environment: - REDIS_URL=redis://redis:6379 - GPU_SIDECARS=192.168.68.15:8090,192.168.68.8:8090,192.168.68.110:8090 healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3000/health')"] interval: 15s timeout: 5s retries: 3 depends_on: - redis volumes: redis-data: pgdata: