8bcb391455
tera.lumbridgecorp.com is live and the Phaser 2D world at world1 is retired — 301 to Tera, containers stopped rather than removed so the decision is reversible for as long as the images exist. Worth writing down what the deploy actually needs, because it is almost nothing: a file server and a default-src 'self' policy. No API, no keys, no account. The one non-obvious header is img-src needing data: and blob:, and that is a consequence of a licensing choice rather than a technical one — every texture is drawn on a canvas at runtime because a texture that is code has no provenance question. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
50 lines
1.7 KiB
Markdown
50 lines
1.7 KiB
Markdown
# 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.
|