events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; resolver 127.0.0.11 valid=30s; map $host $dashboard_ui_url { default http://harness-dashboard:3000; } map $host $litellm_backend_url { default http://harness-litellm:4000; } # ════════════════════════════════════════════════════════════ # Server :80 — Lean single-layer entrypoint # All API paths route directly to LiteLLM. # harness-router fully deprecated. # ════════════════════════════════════════════════════════════ server { listen 80; # Authentik OIDC subrequest location /authentik/auth { internal; proxy_pass https://auth.sysloggh.net/outpost.goauthentik.io/auth/nginx; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URL $scheme://$http_host$request_uri; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # ── LiteLLM API (replaces router /v1/) ── location /v1/ { proxy_pass $litellm_backend_url; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Authorization $http_authorization; proxy_connect_timeout 10s; proxy_read_timeout 600s; proxy_buffering off; } # ── LiteLLM admin (replaces router /admin/) ── location /admin/ { proxy_pass $litellm_backend_url; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Authorization $http_authorization; proxy_read_timeout 600s; } # ── LiteLLM stream ── location /stream { proxy_pass $litellm_backend_url/stream; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; } # ── API passthrough ── location /api/ { proxy_pass $litellm_backend_url/; proxy_http_version 1.1; proxy_set_header Host $host; } # ── Dashboard ── location /dashboard/ { proxy_pass $dashboard_ui_url/; proxy_http_version 1.1; proxy_set_header Host $host; } # ── GPU Fleet Dashboard ── location /gpu/ { proxy_pass http://192.168.68.24:9100/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 60s; } # ── LiteLLM redirect ── location = /litellm { return 301 /litellm/; } # ── Health: redirect /health (auth-required) → /health/liveliness (no-auth) ── location = /litellm/health { return 301 /litellm/health/liveliness; } # ── LiteLLM static assets ── location /litellm-asset-prefix/ { proxy_pass $litellm_backend_url; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 10s; proxy_read_timeout 60s; } # ── LiteLLM admin UI and API (strips /litellm prefix) ── location /litellm/ { rewrite ^/litellm(/.*)$ $1 break; proxy_pass $litellm_backend_url; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_read_timeout 600s; proxy_set_header Authorization $http_authorization; } # ── Auth proxy to Authentik ── location /application/o/ { proxy_pass https://192.168.68.11; proxy_ssl_verify off; proxy_set_header Host auth.sysloggh.net; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 10s; proxy_read_timeout 30s; } # ── Prometheus metrics (LiteLLM exposes at /metrics) ── location /metrics { proxy_pass $litellm_backend_url/metrics; proxy_http_version 1.1; proxy_set_header Host $host; } # ── Router paths — deprecated, redirect to equivalents ── location /router/ { return 301 /litellm/; } location /health/unified { return 301 /gpu/gpu-data; } location /metrics/circuit-breaker { return 410; } # ── Health: no-auth LiteLLM liveliness ── location /health { proxy_pass $litellm_backend_url/health/liveliness; proxy_http_version 1.1; proxy_set_header Host $host; } # ── UI / Docs convenience redirects (additive 2026-09-11) ── # Canonical app path is /litellm/. These 301s make bare # /ui/ and /docs resolve. No new auth surface; no OIDC impact. location = /ui { return 301 /litellm/ui/; } location /ui/ { return 301 /litellm$request_uri; } location = /docs { return 301 /litellm/docs; } location = /docs/ { return 301 /litellm/docs; } # ── 404 for everything else ── location / { return 404; } } }