Two-stage build: node builds the static bundle, nginx serves it. The bundle is
built against a placeholder base token that the entrypoint rewrites to $BASE_URL
at start, so one image serves from any path without a rebuild.
nginx config caches hashed assets forever, never caches index.html, and applies
security headers (CSP, no framing, no referrer) suited to an app that handles
cloud credentials client-side.
.gitattributes pins LF on the container-consumed files, since core.autocrlf
would otherwise give the entrypoint a CRLF shebang.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>