events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; upstream django { server django:8701; } upstream fastapi { server fastapi:8702; } upstream timeline { server timeline:5173; } upstream chunker { server chunker:5174; } upstream minio { server minio:9000; } upstream detection { server detection:5175; } upstream envoy { server envoy:8090; } server { listen 80; server_name mpr.local.ar; # Landing page location = / { root /etc/nginx; try_files /landing.html =404; } # Django Admin location /admin { proxy_pass http://django; 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 X-Forwarded-Proto $scheme; } # Django static files location /static { proxy_pass http://django; proxy_set_header Host $host; } # FastAPI — trailing slash strips /api prefix before forwarding location /api/ { proxy_pass http://fastapi/; 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 X-Forwarded-Proto $scheme; } # Timeline UI location /timeline/ { proxy_pass http://timeline; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Detection UI location /detection/ { proxy_pass http://detection; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Vite HMR websocket (detection) location /detection/@vite { proxy_pass http://detection; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } # Detection API (replay, retry, checkpoints) location /api/detect/ { proxy_pass http://fastapi/detect/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # SSE streams — disable buffering for realtime delivery location /api/detect/stream/ { proxy_pass http://fastapi/detect/stream/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; chunked_transfer_encoding on; } # Chunker UI location /chunker/ { proxy_pass http://chunker; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } # Vite HMR websocket (timeline) location /timeline/@vite { proxy_pass http://timeline; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } # Vite HMR websocket (chunker) location /chunker/@vite { proxy_pass http://chunker; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } # Media files - proxied from MinIO (local) or S3 (AWS) location /media/in/ { proxy_pass http://minio/mpr-media-in/; proxy_set_header Host $http_host; } location /media/out/ { alias /app/media/out/; autoindex on; } # gRPC-Web proxy via Envoy location /grpc-web/ { proxy_pass http://envoy/; 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 X-Forwarded-Proto $scheme; proxy_read_timeout 600s; # Critical for streaming: disable nginx response buffering proxy_buffering off; proxy_cache off; chunked_transfer_encoding on; } } }