events {} http { server { listen 80; server_name localhost; # Allow uploads up to 100 MB client_max_body_size 100m; location / { proxy_pass http://ui:5173; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /ws { proxy_pass http://ui:5173; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /socket.io/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://socket:8084/socket.io/; } # Serve uploaded media files directly from the shared volume location /media/ { alias /media/; add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri =404; } location /api/ { rewrite ^/api/(.*) /$1 break; proxy_pass http://gateway:8084; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 300s; proxy_send_timeout 300s; } location ~ ^/feeds/.+ { rewrite ^/feeds/(.*) /$1 break; proxy_pass http://feed-aggregator:3010; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # Regex match requires at least one character after /scheduler/ so that # a bare /scheduler (Vue Router page) is never redirected here. location ~ ^/scheduler/.+ { rewrite ^/scheduler/(.*) /$1 break; proxy_pass http://scheduler:3011; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }