The portal's copy of the dashboard is the `appshell` target of
backend/Dockerfile (18 MB instead of the 252 MB nginx image); the nginx
frontend Dockerfile, its confs and csp.check.ts are gone, since the app and
the hub both hash the CSP from the index.html they serve.
The runtime image copies the 4 MB git binary alone: the store's init, add,
commit, gc and rev-parse are builtins, and a build-time round trip fails the
build if that ever changes. About 100 MB of perl and helpers less.
The bundled Redis's overcommit warning and FastMCP's lifespan warning no
longer greet every `docker logs`.
Every service builds with `context: ..`, and Docker only consults the
.dockerignore at the context root — the copies under frontend/ and backend/
never applied, so the host's dist/, node_modules/ and caches were shipped
into each build context.