fix(caddy/oci): no-cache SPA routes + ship theme-init.js (PMS-687) #453
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/PMS-687-spa-cache-and-theme-init"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
PMS-687: production sign-in fails (callback returns empty/corrupted HTML)
The fix lands in mokosh-apps (the static host), as the ticket anticipated.
Root cause
The Caddyfile cached every response
immutable(max-age 1y) by default and only excepted/,*.html,/_mokosh_config.jsback to no-cache. Client-side routes served index.html viatry_files(e.g./auth/callback) missed that exception and were pinned in the browser for a year. Verified in prod:GET https://msp.a8n.systems/auth/callbackreturnscache-control: public, max-age=31536000, immutable.A stale/corrupted callback page then survives both a redeploy (the pinned index.html references the previous content-hashed JS
mokosh-apps-dxh<hash>.js, which 404s after a new build) and a server restart (a browser cache is not clearable server-side). That matches every symptom: empty/corrupted callback HTML on reload, nothing in the mokosh-server logs (it is served by Caddy, not the API), and restart not helping.Secondary bug found:
/assets/theme-init.js404s in prod (served as index.html, text/html) ->Uncaught SyntaxError: Unexpected token '<'. The file exists in the repo butdx buildnever emits it and the Dockerfile did not copy it.Changes
no-cache, no-store, must-revalidate; opt only content-addressed assets under/assets+/wasmback intoimmutable(their filenames carry a content hash). Afile {path}guard keeps a missing asset (served as index.html) from being pinned immutable, andtheme-init.js(the one stable-named script under/assets) is excepted back to no-cache.assets/theme-init.jsinto the Caddy web root's/assetsso it is served as JS.Verification
caddy validate+ a container run of the new Caddyfile against a representative rootfs:/,/index.html,/auth/callback,/dashboard/_mokosh_config.js/assets/theme-init.js/assets/<missing>.js/assets/mokosh-apps-dxh<hash>.js/wasm/mokosh-apps_bg.wasmStaleness note (ruled out)
At investigation time all three components were near-current: mokosh-apps
8a669a7(today), mokosh-servera317a14(current main, built 07-24), bunyip0.8.0. The original failure is most consistent with the immutable-cache trap pinning a bad response during the earlier stale-deploy window. A full production sign-in should be re-observed after this deploys (AC #5) - I could not reproduce the empty/corrupted response from a clean external fetch (no browser cache), so an observed interactive run is needed.🤖 Generated with Claude Code
The Caddyfile cached every response `immutable` (max-age 1y) by default and only excepted `/`, `*.html`, and `/_mokosh_config.js` back to no-cache. Client-side routes served index.html via `try_files` (e.g. `/auth/callback`) missed that exception and were pinned in the browser for a year. A stale or corrupted callback page then survived both a redeploy (the pinned index.html references the previous content-hashed JS, which 404s after a new build) and a server restart (a browser cache cannot be cleared server-side) - the PMS-687 symptom: sign-in callback returns empty/corrupted HTML on reload, nothing in the server logs, restart does not help. Invert the policy: default `no-cache, no-store, must-revalidate`, and opt only the content-addressed build assets under `/assets` and `/wasm` back into `immutable` (their filenames carry a content hash, so a new build ships new URLs). A `file {path}` guard keeps a MISSING asset - which `try_files` serves as index.html - from being pinned immutable as HTML, and `theme-init.js` (the one stable-named script under `/assets`) is excepted back to no-cache. Verified with `caddy validate` + a container run: `/`, `/index.html`, `/auth/callback`, `/dashboard`, `/_mokosh_config.js`, `/assets/theme-init.js`, and any missing `/assets/*` all return no-cache; hashed `/assets/*.js` and `/wasm/*.wasm` return immutable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvB249F2SV9SBe3cBKRjcS