Nginx (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/danizd/urbanviable/llms.txt
Use this file to discover all available pages before exploring further.
urbanviable-web) is the public entry point for UrbanViable. The current nginx/conf.d/default.conf serves three concerns from a single HTTP virtual host: the compiled React SPA, a static JSON data-freshness endpoint mapped from last_update.json, and direct static file serving of tile data. TileServer GL handles its own port (8080) separately on the same host.
nginx/conf.d/default.conf
Location blocks explained
location / — React SPA fallback
frontend/build/ on the host, mounted read-only into /usr/share/nginx/html). The try_files directive implements the SPA routing pattern: Nginx first tries to serve the exact path as a file, then as a directory, and finally falls back to /index.html. This ensures that client-side routes such as /scouting or /how-to-use are handled by React Router rather than returning a 404.
location /api/status — static data freshness endpoint
last_update.json file generated by the ETL pipeline. The frontend’s DataStatus component polls this endpoint to display when the underlying census data was last refreshed. The file is available inside the container at /data/last_update.json via the ./tiles_data:/data:ro bind mount. Responses are cached for 1 hour (max-age=3600).
location /data/ — static tile data files
/data/ directory inside the container, which is the same ./tiles_data bind mount. This location exposes JSON metadata files and other static data assets that the frontend or developer tooling may request.
SSL configuration
The currentnginx/conf.d/default.conf listens on HTTP port 80. The ./certs directory is bind-mounted into the container at /etc/letsencrypt:ro in anticipation of TLS termination. To enable HTTPS, replace the single server block with a redirect server and a TLS server:
Adding a /tiles/ reverse proxy
The Vite dev server (vite.config.js) already proxies /tiles to http://127.0.0.1:8080/data for local development. To mirror this in the production Nginx config, add a proxy location to nginx/conf.d/default.conf:
HTTP security headers
The following headers should be applied in the mainserver block so they are present on every response, regardless of location:
| Header | Value | Purpose |
|---|---|---|
Strict-Transport-Security | max-age=31536000; includeSubDomains | Forces HTTPS for one year; prevents protocol downgrade |
X-Content-Type-Options | nosniff | Prevents MIME-type sniffing attacks |
X-Frame-Options | DENY | Blocks the site from being embedded in an iframe |
X-XSS-Protection | 1; mode=block | Legacy XSS filter for older browsers |
Cache invalidation after ETL updates
The/data/ and /api/status locations cache responses for 1 hour. After an ETL update, users will automatically receive fresh data within that window. To force an immediate client-side cache bust for tile URLs, update the REACT_APP_TILE_URL variable in .env with a version query parameter before rebuilding the frontend:
?v=2026 parameter is ignored by TileServer GL but is treated as a distinct URL by the browser cache, so all clients will fetch fresh tiles on the next page load. Increment the version number with each new annual ETL run.