From 873836725822eda6e5f2304a0bc2d79718b3a175 Mon Sep 17 00:00:00 2001 From: Kartios Date: Wed, 19 Aug 2026 03:35:30 -0700 Subject: [PATCH] docs: make static deploy cache-safe --- deploy/Caddyfile.snippet | 12 ++++++++++++ deploy/STATIC.md | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/deploy/Caddyfile.snippet b/deploy/Caddyfile.snippet index 4de1fa7..181dd2a 100644 --- a/deploy/Caddyfile.snippet +++ b/deploy/Caddyfile.snippet @@ -12,6 +12,10 @@ # tera.lumbridgecorp.com { # import tera_api # root * /srv/tera/dist +# @assets path /assets/* +# header @assets Cache-Control "public, max-age=31536000, immutable" +# @documents not path /assets/* +# header @documents Cache-Control "no-cache" # file_server # } # @@ -32,6 +36,10 @@ # office.lumbridgecorp.com { # import tera_api # root * /srv/tera/dist # the SAME root as tera., not a copy +# @assets path /assets/* +# header @assets Cache-Control "public, max-age=31536000, immutable" +# @documents not path /assets/* +# header @documents Cache-Control "no-cache" # try_files {path} {path}/index.html /office.html # file_server # } @@ -42,6 +50,10 @@ # either. The only line that differs between the two site blocks is the # `try_files` fallback. # +# Keep the cache rules in the static handler when the site also serves the API. +# The HTML shells and RELEASE_SHA are stable names and must revalidate after a +# deploy; Vite's /assets/* files are content-addressed and may stay immutable. +# # A deployment that skips this is not broken: the office door keeps working and # simply unfurls with the city's card, which is what it did before there was a # second shell at all. diff --git a/deploy/STATIC.md b/deploy/STATIC.md index 3931c3e..91bad71 100644 --- a/deploy/STATIC.md +++ b/deploy/STATIC.md @@ -28,6 +28,10 @@ is sufficient; the build references no external fonts, CDNs or images. tera.example.com { root * /var/www/tera encode zstd gzip + @assets path /assets/* + header @assets Cache-Control "public, max-age=31536000, immutable" + @documents not path /assets/* + header @documents Cache-Control "no-cache" try_files {path} {path}/index.html /index.html file_server header { @@ -40,6 +44,14 @@ tera.example.com { } ``` +The cache split is part of the deployment contract. Vite fingerprints files in +`/assets/`, so those responses can be immutable. The HTML shells and release +metadata are not fingerprinted and must revalidate; otherwise a browser can +keep the previous shell after an atomic deploy even though the new assets and +`RELEASE_SHA` are already live. Keep both header rules inside the static +`handle` when the same site also proxies `/api/*`, so API routes retain their +own cache policy. + `try_files … /index.html` matters if you add client-side routes later: without it a route that exists only in JavaScript 404s for anyone who types it or refreshes on it.