Add generators.${BASE_DOMAIN}: a pinned fork of misode.github.io served
with its own mcmeta + vanilla-mcdoc mirror, so it works with zero internet
at the LAN party. Fork lives in ulicraft-generators (branch ulicraft),
pinned at upstream 2bfe5522.
The app is 100% client-side: every data fetch comes from the player's
browser, not from cochi. So offline capability is entirely about which
origins the bundle refers to, plus a mirror to serve them from. The vhost
sets Content-Security-Policy with connect-src 'self' as ENFORCEMENT: an
external origin that sneaks back in (or returns via an upstream merge)
then breaks loudly in prod, on an ordinary day, instead of silently at the
venue with no internet to debug it.
sync-generators-data.sh mirrors ~109M: the 1.21.1 summary/data/atlas tags,
assets-tiny (assets minus hundreds of MB of .ogg — hence no sounds
generator), vanilla-mcdoc symbols.json, and summary/versions/data.min.json,
which comes from a BRANCH head rather than a version tag and runs during
Spyglass init. It verifies a sentinel file per source instead of trusting a
clean clone exit, since a renamed upstream path would otherwise sync
"successfully" and only fail in the browser at the party.
The container serves the bundle and the mirror on one origin, so there is
no CORS, no second cert and no second DNS name.
DEPLOY ORDER MATTERS. GENERATORS_REPO must be set in cochi's .env BEFORE
pulling this: compose uses ${GENERATORS_REPO:?...}, and an unset required
variable makes docker compose fail to parse the file — taking down every
service including Minecraft, not just this one. Full runbook and the rest
of the prerequisites: plan/21-generators.md.
Verified offline in real Chromium with every non-origin request aborted:
zero off-origin attempts, zero same-origin failures, zero console errors,
generators rendering schemas and live JSON.
37 lines
2.1 KiB
Plaintext
37 lines
2.1 KiB
Plaintext
# Generators — a pinned, self-contained fork of misode.github.io (Minecraft
|
|
# data pack generators) at generators.${BASE_DOMAIN}. Full design: plan/21-generators.md.
|
|
#
|
|
# The container serves BOTH the app bundle and the ~107M offline data mirror
|
|
# (mcmeta + vanilla-mcdoc) that tooling/sync-generators-data.sh produces, so
|
|
# the whole thing is single-origin by construction.
|
|
#
|
|
# WHY THAT MATTERS: this app is 100% client-side. Every data fetch comes from
|
|
# the PLAYER'S BROWSER, not from this host. Blocking the container's egress
|
|
# proves nothing, and "cochi has no WAN at the party" protects nothing — a
|
|
# single leftover upstream URL simply fails in the browser, at the venue, with
|
|
# no internet available to debug it.
|
|
http://generators.{$BASE_DOMAIN} {
|
|
# The CSP is the ENFORCEMENT mechanism for offline operation, not decoration.
|
|
#
|
|
# `connect-src 'self'` is the load-bearing directive: it hard-blocks any
|
|
# fetch/XHR to an origin we do not serve. If an upstream URL survives the
|
|
# fork patch — or a future upstream merge reintroduces one — it breaks
|
|
# LOUDLY in prod, on an ordinary day with internet available to fix it,
|
|
# instead of silently at the party. This is the same lesson as the filestash
|
|
# `http://https://` incident: a 200 on `/` proves the server is up, never
|
|
# that the app works.
|
|
#
|
|
# script-src/style-src stay permissive ON PURPOSE for now. Spyglass and
|
|
# deepslate may need wasm/eval and this has NOT been characterised yet;
|
|
# tightening them is a post-party task. Loosening `connect-src` is not —
|
|
# that one is the whole point.
|
|
header {
|
|
Content-Security-Policy "default-src 'self'; connect-src 'self'; img-src 'self' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; worker-src 'self' blob:; base-uri 'self'; form-action 'self'"
|
|
# The mirror is pinned to one MC version and changes only when
|
|
# sync-generators-data.sh is re-run, so let browsers keep it. This is
|
|
# also what makes a second visit cheap on a LAN with no upstream.
|
|
?Cache-Control "public, max-age=604800"
|
|
}
|
|
reverse_proxy generators:80
|
|
}
|