server { listen 8080; listen 443 ssl; server_name _; client_max_body_size 25M; ssl_certificate /certs/public.crt; ssl_certificate_key /certs/private.key; # ssl on; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; ssl_prefer_server_ciphers on; root /usr/share/nginx/html; index index.html; # Standard MIME types include /etc/nginx/mime.types; # Additional MIME types required by WebXR/Needle assets types { application/wasm wasm; model/gltf-binary glb; image/ktx2 ktx2; } # SPA fallback + CORS location / { # Handle CORS preflight requests quickly if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Max-Age' 86400 always; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } # CORS headers for actual requests add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; add_header 'Cross-Origin-Resource-Policy' 'cross-origin' always; try_files $uri $uri/ /index.html; } }