From bf770fed8310ddace910712010cae8eef07ca16d Mon Sep 17 00:00:00 2001 From: Lotus CI Date: Sun, 18 Oct 2026 01:26:02 -0400 Subject: [PATCH] fix(cinny-web): no-cache for the app shell on SPA routes; keep old hashed assets 14 days (#23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPA URLs (/, /home/…, /login/…) are rewritten to /index.html inside location /, which set no cache headers, so browsers heuristically reused a stale shell after a deploy, and rsync --delete had just removed the assets it referenced: a blank app until the shell expired. Send no-cache for the rewritten shell (map on $uri; location / now includes the security headers, since add_header drops the inherited ones), and stop deleting previous builds' hashed assets: prune after 14 days. Fixes #23 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5 --- cinny/lotus_deploy.sh | 8 +++++++- cinny/nginx.conf | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cinny/lotus_deploy.sh b/cinny/lotus_deploy.sh index 2eb0f73..f1e1ab1 100755 --- a/cinny/lotus_deploy.sh +++ b/cinny/lotus_deploy.sh @@ -160,7 +160,13 @@ echo "[$(date '+%Y-%m-%d %H:%M:%S')] Deploying to $WEBROOT..." # /var/www/html/config.json by lxc106-cinny.sh. The build ships a DEV default # (allowCustomHomeservers:true); rsyncing it would clobber the production config # on every deploy. Keep the app bundle and the runtime config separate. -rsync -a --delete --exclude config.json dist/ "$WEBROOT/" +# [matrix #23] Keep the previous builds' hashed assets for a while: a browser +# still holding an older index.html (or service-worker precache) asks for its +# assets/index-.js, and deleting them on every deploy broke the app +# for those users until their cached shell expired. Prune after 14 days. +rsync -a --delete --exclude config.json --exclude assets/ dist/ "$WEBROOT/" +rsync -a dist/assets/ "$WEBROOT/assets/" +find "$WEBROOT/assets" -type f -mtime +14 -delete echo "[$(date '+%Y-%m-%d %H:%M:%S')] ===== Deploy complete ($VITE_APP_VERSION) =====" diff --git a/cinny/nginx.conf b/cinny/nginx.conf index 6e4a797..97dbd41 100644 --- a/cinny/nginx.conf +++ b/cinny/nginx.conf @@ -1,3 +1,12 @@ +# [matrix #23] SPA routes (/, /home/…, /login/…) are rewritten to /index.html +# inside `location /`, where no cache headers were set: browsers then reused a +# heuristically fresh shell after a deploy and requested deleted assets. Only +# the rewritten shell gets no-cache; other files there keep their defaults. +map $uri $lotus_shell_cache_control { + /index.html "no-cache, no-store, must-revalidate"; + default ""; +} + server { listen 80; listen [::]:80; @@ -99,6 +108,9 @@ server { } location / { + # add_header here drops the server-level headers, so include them again. + include snippets/cinny-security-headers.conf; + add_header Cache-Control $lotus_shell_cache_control always; rewrite ^/config\.json$ /config.json break; rewrite ^/manifest\.json$ /manifest.json break; rewrite ^/sw\.js$ /sw.js break;