# Hosting the static build Tera's map view is a static bundle. It makes **no network calls at all** — the sun is computed locally by `src/engine/solar.ts`, the traffic is simulated, and the office is a data file — so it needs a file server and nothing else. No API, no keys, no account. ```bash npm ci npm run build # -> dist/ ``` Serve `dist/` from anything. A Content-Security-Policy of `default-src 'self'` is sufficient; the build references no external fonts, CDNs or images. ## Caddy ``` tera.example.com { root * /var/www/tera encode zstd gzip try_files {path} {path}/index.html /index.html file_server header { Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; object-src 'none'" } } ``` `try_files … /index.html` matters if you add client-side routes later: without it a route that exists only in JavaScript 404s for anyone who types it or refreshes on it. `img-src` needs `data:` and `blob:` because every texture in the asset library is drawn on a canvas at runtime rather than shipped as a file — see ARCHITECTURE.md §3.1 for why that is a licensing decision and not a technical one. ## Serving the API too Only needed for live weather, real ADS-B, or markers from an external source. The map runs fully without it. See `deploy/tera-api.service`, `deploy/Caddyfile.snippet` and `deploy/docker-compose.yml`. ## Base path Deployed at a subdomain root, no configuration is needed. Under a subpath, set `TERA_BASE` at build time (`TERA_BASE=/tera/ npm run build`) — the trailing slash matters, since every asset URL resolves against it.