server { listen 80; server_name _; # accept requests by IP — fine for local network # ── Frontend (React build) ───────────────────────────────────────── root /opt/music-orchestrator/frontend/dist; index index.html; # React Router: unknown paths fall back to index.html location / { try_files $uri $uri/ /index.html; } # ── API (FastAPI backend) ────────────────────────────────────────── location /api/ { proxy_pass http://127.0.0.1:8000; 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; # Downloads can take a while — don't time out too early proxy_read_timeout 600s; proxy_send_timeout 600s; # Don't buffer file downloads through nginx memory proxy_buffering off; # Allow large upload/download bodies (for file transfers) client_max_body_size 0; } # ── Compression ──────────────────────────────────────────────────── gzip on; gzip_types text/plain text/css application/javascript application/json image/svg+xml; gzip_min_length 1024; # ── Static asset caching ─────────────────────────────────────────── location ~* \.(js|css|png|jpg|jpeg|svg|ico|woff2?)$ { expires 7d; add_header Cache-Control "public, immutable"; } }