- Added extra_hosts for auth.sysloggh.net to LiteLLM container - Fixed DOCS_URL=/docs (was /litellm/docs - path mismatch) - Added Authentik self-signed cert to CA bundle - Added nginx auth proxy for token/userinfo endpoints (SSL verify off) - Changed OIDC token/userinfo endpoints to use nginx internal proxy - Admin UI serving correctly on :4001/ui/ and /litellm/ui/ - Swagger API docs working at /docs and /litellm/docs - ReDoc API docs working at /redoc and /litellm/redoc - OIDC login flow verified working end-to-end
175 lines
6.0 KiB
Nginx Configuration File
175 lines
6.0 KiB
Nginx Configuration File
events {
|
|
worker_connections 1024;
|
|
}
|
|
|
|
http {
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
sendfile on;
|
|
keepalive_timeout 65;
|
|
|
|
# Docker DNS resolver — forces request-time resolution for variable-based proxy_pass.
|
|
# Without this, nginx resolves upstream hostnames at config load time,
|
|
# which fails when Docker DNS (127.0.0.11) isn't ready yet on container start.
|
|
resolver 127.0.0.11 valid=30s;
|
|
|
|
# Dynamic upstream resolution via nginx variables.
|
|
# Using $var in proxy_pass forces request-time resolution through the resolver.
|
|
# Without this, 'host not found in upstream' crashes nginx when Docker DNS is slow.
|
|
map $host $router_api_url {
|
|
default http://harness-router:9000;
|
|
}
|
|
map $host $dashboard_ui_url {
|
|
default http://harness-dashboard:3000;
|
|
}
|
|
map $host $litellm_backend_url {
|
|
default http://harness-litellm:4000;
|
|
}
|
|
# ════════════════════════════════════════════════════════════════
|
|
# Server :80 — harness entrypoint
|
|
# dashboard (/), router API (/v1/, /admin/, /stream, /api/, /metrics),
|
|
# router fallback, health
|
|
# ════════════════════════════════════════════════════════════════
|
|
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;
|
|
}
|
|
|
|
# 2-Layer: /v1/ → router (existing keys work unchanged)
|
|
location /v1/ {
|
|
proxy_pass $router_api_url;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Authorization $http_authorization;
|
|
proxy_connect_timeout 10s;
|
|
proxy_read_timeout 600s;
|
|
proxy_buffering off;
|
|
error_page 502 503 = @router_fallback;
|
|
}
|
|
|
|
location @router_fallback {
|
|
proxy_pass $router_api_url;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Authorization $http_authorization;
|
|
proxy_read_timeout 600s;
|
|
}
|
|
|
|
location /admin/ {
|
|
proxy_pass $router_api_url;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Authorization $http_authorization;
|
|
proxy_read_timeout 600s;
|
|
}
|
|
|
|
location /stream {
|
|
proxy_pass $router_api_url/stream;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_buffering off;
|
|
}
|
|
|
|
location /api/ {
|
|
proxy_pass $router_api_url/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
|
|
|
|
location /dashboard/ {
|
|
proxy_pass $dashboard_ui_url/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
# LiteLLM redirect target /litellm (no trailing slash) -> add slash back
|
|
location = /litellm {
|
|
return 301 /litellm/;
|
|
}
|
|
|
|
# LiteLLM static assets (Next.js chunks, CSS, fonts)
|
|
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 proxy — strip /litellm prefix so /litellm/ui/ → /ui/
|
|
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 Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_buffering off;
|
|
}
|
|
|
|
# Auth proxy to Authentik — accepts HTTP from LiteLLM, proxies HTTPS to .11 with SSL verify off
|
|
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;
|
|
}
|
|
|
|
# All other requests → 404
|
|
location / {
|
|
return 404;
|
|
}
|
|
|
|
location /metrics/ {
|
|
proxy_pass $router_api_url/metrics/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location /metrics/circuit-breaker {
|
|
proxy_pass $router_api_url/metrics/circuit-breaker;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location /router/ {
|
|
proxy_pass $router_api_url/;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location /health/unified {
|
|
proxy_pass $router_api_url/health/unified;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location /health {
|
|
proxy_pass $router_api_url/health;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
}
|
|
|
|
}
|