b85a9e1b9b
Caddy's `file_server` did not set Cache-Control on the SvelteKit build, so browsers fell back to heuristic caching keyed off Last-Modified. On the long-lived dev environment the heuristic window leaves the previous deploy's `index.html` cached for minutes-to-hours, and Safari combined that with stale conditional requests into a visible multi-second freeze on every reload (the reproduction was "private window reloads instantly, normal window hangs; clearing Safari caches restores normal speed"). Push delivery itself works — heartbeat keeps the SubscribeEvents stream alive — but the bundle path stalls behind the browser revalidating a chain of stale chunks. Mirror the standard SvelteKit cache split inside both Caddyfiles: - `_app/immutable/*` — hash-named JS/CSS chunks Vite emits with content-addressed file names — `Cache-Control: public, max-age=31536000, immutable`. Safe to cache forever because the name changes whenever the content does, so the next deploy serves new files under new URLs. - Everything else (`index.html` fallback via `try_files`, `env.js`, `version.json`, `core.wasm`, `wasm_exec.js`, `favicon.svg`) — `Cache-Control: no-cache, must-revalidate`. The browser still uses the cached body when the ETag matches, but it always asks first; a fresh deploy reaches the user on the next reload without a manual cache clear. Smoke-tested locally: a docker-run Caddy with this config returns the immutable header only for `/_app/immutable/*` and the no-cache header for `/index.html`, `/env.js`, and the SPA-fallback path `/some/route`. The Caddyfile passes `caddy validate` in both `Caddyfile.dev` and `Caddyfile.prod`; the pre-existing formatting warning on line 7 is untouched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
26 lines
874 B
Caddyfile
26 lines
874 B
Caddyfile
# Production placeholder. Mirrors `Caddyfile.dev` but uses real
|
|
# hostnames and lets Caddy auto-provision TLS certificates. Not used
|
|
# until prod-deploy plumbing exists; kept under version control so the
|
|
# dev/prod surface stays symmetric.
|
|
|
|
www.galaxy.com {
|
|
root * /srv/galaxy-ui
|
|
|
|
# Mirrors the cache policy `Caddyfile.dev` documents in detail:
|
|
# SvelteKit's hash-named `_app/immutable/*` is safe to cache
|
|
# forever; everything else must revalidate so a deploy reaches
|
|
# the browser without a manual cache clear.
|
|
@immutable path /_app/immutable/*
|
|
header @immutable Cache-Control "public, max-age=31536000, immutable"
|
|
@dynamic not path /_app/immutable/*
|
|
header @dynamic Cache-Control "no-cache, must-revalidate"
|
|
|
|
try_files {path} /index.html
|
|
file_server
|
|
encode zstd gzip
|
|
}
|
|
|
|
api.galaxy.com {
|
|
reverse_proxy galaxy-api:8080
|
|
}
|