# Rippy UI: statische Dateien + API-Proxy. # /api/* wird an den api-Container durchgereicht (Präfix wird entfernt), # alles andere ist das gebaute React-UI. Damit braucht der Browser nur # EINEN Origin — kein hartkodiertes localhost, kein CORS-Gefrickel. server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://api:8000/; proxy_http_version 1.1; proxy_set_header Host $host; # ⚠️ OHNE DIESE ZEILEN TEILEN SICH ALLE CLIENTS EIN RATE-LIMIT # # Die API begrenzt Anfragen pro Client-IP (ratelimit.py). Ohne # weitergegebene Adresse sah sie als Absender immer DIESEN Container — # Browser, zweiter Tab und der Windows-Tray landeten also in einem # gemeinsamen Eimer. Gemessen am 26.07.2026: 812 von 876 Anfragen kamen # scheinbar von 172.19.0.6, und das UI bekam laufend HTTP 429. proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # SSE (/api/stream/jobs) braucht ungepufferte, lange Verbindungen: proxy_buffering off; proxy_read_timeout 3600s; # Der nginx-Default ist 1 MB. Eine echte KEYDB.cfg ist deutlich groesser, # der Upload ueber POST /api/system/keydb wuerde also schon hier mit # 413 abgewiesen — die API bekaeme die Anfrage nie zu sehen und das UI # haette keinen detail-Text, den es anzeigen koennte. 64m entspricht dem # Limit MAX_KEYDB_BYTES in makemkv_daten.py. client_max_body_size 64m; } location / { try_files $uri /index.html; } }