feat(map): self-hosted MapLibre GL + PMTiles vector map
Replace Leaflet + OSM raster tiles with MapLibre GL JS + PMTiles: - Full continental US vector tiles (8GB PMTiles, zoom 0-14 with overzoom) - Dark theme via @protomaps/basemaps (official supported path) - Clustered device markers with status colors (green/yellow/red) - Popup cards show CPU, memory, wireless client count + avg signal - Font glyphs proxied through nginx, sprites served locally - Zero third-party requests from the browser - Fleet summary SQL now includes wireless client count and avg signal via LEFT JOIN LATERAL on wireless_links Also removes alert toast spam and fixes map container height. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,7 @@ server {
|
||||
|
||||
# CSP for React SPA with Tailwind CSS and Leaflet maps
|
||||
# worker-src required for SRP key derivation Web Worker (Safari won't fall back to script-src)
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self' ws: wss:; worker-src 'self' blob:; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; connect-src 'self' ws: wss:; worker-src 'self' blob:; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;
|
||||
|
||||
# Proxy API requests to the backend service
|
||||
# The api container is reachable via Docker internal DNS as "api" on port 8000
|
||||
@@ -91,7 +91,7 @@ server {
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
}
|
||||
|
||||
# Serve PMTiles with byte range support (protomaps-leaflet reads via HTTP Range)
|
||||
# Serve PMTiles with byte range support
|
||||
location /tiles/ {
|
||||
add_header Access-Control-Allow-Origin "*" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
@@ -101,6 +101,17 @@ server {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Proxy map font glyphs (MapLibre requests many glyph ranges dynamically)
|
||||
location ~ ^/map-fonts/(.+)$ {
|
||||
resolver 127.0.0.11 8.8.8.8 valid=300s ipv6=off;
|
||||
set $font_path $1;
|
||||
proxy_pass https://protomaps.github.io/basemaps-assets/fonts/$font_path;
|
||||
proxy_ssl_server_name on;
|
||||
proxy_set_header Host protomaps.github.io;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
# Serve static assets with long cache headers
|
||||
# Note: add_header in a location block clears parent-block headers,
|
||||
# so we re-add the essential security header for static assets.
|
||||
|
||||
Reference in New Issue
Block a user