fix(nginx-152): корень редиректит на активную сборку — закрыта кэш-мина (ассеты Unity зовутся относительным путём)

- index.html: buildUrl="Build" -> без редиректа ассеты шли как /Build/WebGL.wasm (без номера сборки)
  под immutable 7д -> браузер неделю отдавал старую сборку
- publish-release.sh --activate пишет /etc/nginx/game-active.inc: return 302 /<N>/
- immutable сужен до путей с номером сборки; остальное no-store
- приёмка: / -> 302 /29/, браузер тянет /29/Build/* (все 200), autoclose-check 9/9, testfront цел
- сборка 29 (fix webgl: дым падения и PC URP) опубликована на nginx
This commit is contained in:
Porfiry
2026-09-15 18:34:12 +03:00
parent 85f092ba14
commit 5087c67201
5 changed files with 137 additions and 40 deletions
+35
View File
@@ -258,3 +258,38 @@
пересборку образа на каждый билд игры и не решает вопрос кэша; (б) поднять в LXC не nginx, а
podman-контейнер с nginx — лишний слой на 10 строках конфига; (в) отдавать статику прямо с k3s-Traefik
по PVC — не то, о чём просил владелец (он хотел nginx на проксмоксе).
## ADR-011-доп — корень редиректит на активную сборку (закрыта кэш-мина ADR-010) (2026-09-15)
**Что нашли на сборке 29 (проверка живьём, не по документам).** `index.html` Unity ссылается на
ассеты **относительным** путём (`var buildUrl = "Build"`). Пока корень отдавал файлы напрямую из
`/opt/game/current`, игрок получал ассеты по URL **без номера сборки** — `/Build/WebGL.wasm`,
`/Build/WebGL.data` и т.д. Эти URL между релизами **не меняются**, а в конфиге они попадали под
маску `immutable` (7 суток). Итог: у игравшего игрока браузер неделю держал бы ассеты старой сборки
и молча игнорировал новый билд. То есть моя собственная маска кэша воспроизводила ровно ту мину,
которую ADR-011 объявлял закрытой. Версионирование каталогами **само по себе** её не лечило —
лечило только то, чтобы URL ассетов реально содержали номер сборки.
**Решение.** Корень больше не раздаёт файлы — он **302-редиректит на активную сборку**:
- `publish-release.sh --activate` пишет `/etc/nginx/game-active.inc`:
`location = / { return 302 /<N>/; }` + то же для `/index.html`;
- `include /etc/nginx/game-active.inc;` подключён в server-блок;
- после редиректа `location.pathname` = `/29/`, относительный `buildUrl = "Build"` резолвится
в `/29/Build/…` — версионированный URL, старый URL перестаёт использоваться вовсе;
- маска `immutable` сужена до путей **с номером сборки** (`~^/[0-9]+/…`); всё остальное,
включая неверсионированные ассеты, теперь `no-store` (страховка от отравления кэша).
**Проверено живьём (сборка 29):** `/` → **302 → `/29/`**; браузер приземляется на `/29/` и тянет
`/29/Build/WebGL.wasm`, `/29/Build/WebGL.data`, `/29/Build/WebGL.framework.js` — все 200, ни одной
ошибки в консоли; `/28/`,`/27/` живы; неверсионированный `/Build/WebGL.wasm` → 200 с `cache-control:
no-store`; `/api/state`,`/api/price`,`/solana-rpc/` → 200; сквозная ставка `autoclose-check` — **9/9**;
`testfront` не задет (200).
**Почему не «отдавать корень без редиректа».** Это работало бы (неверсионированные ассеты получили бы
`no-store`), но теряется весь смысл `immutable`-кэширования: ассеты в 52 МБ + 18 МБ перекачивались бы
при каждом заходе. Редирект даёт и корректность, и кэш.
**Остаточный риск.** Игрок, у которого в кэше уже лежат ассеты по **старому** неверсионированному URL
(`/Build/WebGL.wasm`, полученные до этого фикса), один раз может получить старый билд — URL теперь
`no-store`, так что после первой перезагрузки браузер сходит на сервер и получит свежее. Новые
версии этой проблемы не имеют вовсе.