# nginx site config for 200feet — static assets, aggressive compression, # long cache on hashed/static GeoJSON, short cache on HTML so updates ship fast. map $sent_http_content_type $expires { default off; text/html 10m; application/json 1h; application/geo+json 1h; text/css 7d; application/javascript 7d; image/svg+xml 7d; image/png 30d; image/jpeg 30d; font/woff2 30d; } server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; index index.html; # Strong compression -- geojson compresses ~3x. gzip on; gzip_vary on; gzip_comp_level 6; gzip_min_length 256; gzip_proxied any; gzip_types text/plain text/css text/javascript application/javascript application/json application/geo+json application/xml image/svg+xml font/woff2; # NOTE: do NOT redefine types {} here -- a types block in a server scope # REPLACES the inherited /etc/nginx/mime.types instead of extending it, # which makes nginx return application/octet-stream for everything else. # .geojson files end up served as application/json (which fetch().json() # handles fine), since the layer's location adds an explicit type below. expires $expires; add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy strict-origin-when-cross-origin always; # Modest CSP. Leaflet + Turf + CARTO tiles + Google fonts are the third parties. add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https://*.basemaps.cartocdn.com; script-src 'self' https://unpkg.com; style-src 'self' 'unsafe-inline' https://unpkg.com https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self';" always; # Healthcheck for Portainer / Docker location = /healthz { access_log off; add_header Content-Type text/plain; return 200 "ok\n"; } # SPA-style fallback in case we ever add client routing. location / { try_files $uri $uri/ /index.html; } # Data files: longer cache acceptable, content keyed off the build. location /data/ { add_header Cache-Control "public, max-age=3600"; # Ensure JSON-ish content types for .geojson / .json location ~* \.geojson$ { default_type application/geo+json; } location ~* \.json$ { default_type application/json; } try_files $uri =404; } # Don't log favicon / robot probes. location = /favicon.ico { access_log off; log_not_found off; return 204; } location = /robots.txt { access_log off; log_not_found off; return 200 "User-agent: *\nAllow: /\n"; } }