server { listen 80; root /usr/share/nginx/html; # Same-origin API: the SPA calls /api/..., nginx forwards to the backend # container. Mirrors the Vite dev proxy — the frontend build is identical # in both environments. location /api/ { # Match the backend's 5MB CSV cap so oversized uploads are rejected at # the edge, before they ever reach uvicorn. client_max_body_size 5m; proxy_pass http://backend:8000; } # SPA fallback: client-side routes all serve index.html. location / { try_files $uri /index.html; } }