# nginx для раздачи Unity-сборок «Бинарной ракеты» — LXC 152 (game-web, 192.168.76.152) # Файл: /etc/nginx/sites-available/game # # Модель версионирования: # /opt/game/releases// — файлы сборки N (Build/, TemplateData/, index.html) # /opt/game/current -> releases/ — активная сборка (симлинк, переключает publish-release.sh) # # https://smart-updown.binom.pw/ -> 302 на активную сборку (/29/) # https://smart-updown.binom.pw/29/ -> конкретная сборка 29 # https://smart-updown.binom.pw/29/Build/WebGL.data -> ассет сборки 29 # # ⚠️ ПОЧЕМУ КОРЕНЬ РЕДИРЕКТИТ, А НЕ ОТДАЁТ ФАЙЛЫ: # index.html сборки ссылается на ассеты ОТНОСИТЕЛЬНЫМ путём (`buildUrl = "Build"`). # Если отдавать его прямо с корня, ассеты запрашиваются как /Build/WebGL.wasm — БЕЗ номера # сборки. Такой URL между релизами НЕ меняется, а мы отдаём его `immutable` на 7 суток → # браузер игрока неделю держит ассеты старой сборки и игнорирует новый билд (мина из ADR-010). # При редиректе на // все ассеты получают версионированный URL (/29/Build/...), старый URL # просто перестаёт использоваться, и `immutable` становится корректным. # Номер активной сборки пишет publish-release.sh в отдельный include-файл /etc/nginx/game-active.inc. # # API и WebSocket nginx НЕ обслуживает: их забирает Traefik на VDS # (router smart-updown-api: PathPrefix /api,/ws -> куб 192.168.76.120). # Локальные location /api, /ws, /solana-rpc — страховка для запросов, # которые всё же дойдут до nginx (прямой заход по IP, старые сборки). # Ассеты Unity внутри каталога версии неизменяемы -> immutable. # Всё, что НЕ под номером сборки, и index.html -> no-store. map $uri $game_cache_control { default "no-store"; ~^/[0-9]+/.+\.(js|wasm|data|mem|symbols|css|png|jpg|jpeg|gif|svg|woff2?)$ "public, max-age=604800, immutable"; } server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /opt/game/current; index index.html; access_log /var/log/nginx/game-access.log; error_log /var/log/nginx/game-error.log warn; gzip on; gzip_min_length 512; gzip_types application/javascript application/wasm application/json text/css application/octet-stream; add_header Cache-Control $game_cache_control; # --- корень: 302 на активную сборку --------------------------------------- # Файл переписывает publish-release.sh при --activate. include /etc/nginx/game-active.inc; # --- версионированные сборки: /<число>/... ------------------------------- # /29/index.html -> /opt/game/releases/29/index.html location ~ ^/(?[0-9]+)(?/.*)?$ { root /opt/game/releases; try_files /$build$subpath /$build$subpath/ =404; } # --- страховка: API ------------------------------------------------------- # Нормальный /api идёт мимо nginx (Traefik VDS -> куб). Если запрос всё же # пришёл сюда — уходим в куб на k3s-Traefik с правильным Host, дальше # ingress smart-updown-api ведёт в шлюз :8895. location /api { proxy_pass http://192.168.76.120; proxy_set_header Host smart-updown.binom.pw; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_buffering off; } # --- страховка: WebSocket ------------------------------------------------- location /ws { proxy_pass http://192.168.76.120; proxy_set_header Host smart-updown.binom.pw; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; proxy_buffering off; } # --- страховка: Solana RPC ------------------------------------------------- # /solana-rpc/ НЕ ловится PathPrefix /api на VDS, поэтому уходит в корневой # router, т.е. сюда. Старые сборки игры стучатся именно в этот путь. location /solana-rpc/ { proxy_pass http://192.168.76.181:8899/; proxy_set_header Host $host; proxy_http_version 1.1; proxy_read_timeout 300s; } }