Files

110 lines
6.3 KiB
Plaintext

# nginx для раздачи Unity-сборок «Бинарной ракеты» — LXC 152 (game-web, 192.168.76.152)
# Файл: /etc/nginx/sites-available/game
#
# Модель версионирования (два вида сборок, живут рядом):
# /opt/game/releases/<N>/ — номерные релизы (1, 2, 3, … 29) из CI/реестра
# /opt/game/releases/<имя>/ — именованные сборки (например `sol`), присланные zip'ом
# /opt/game/current -> releases/<N> — активная сборка (симлинк, переключает publish-release.sh)
#
# https://smart-updown.binom.pw/ -> 302 на активную сборку (/29/)
# https://smart-updown.binom.pw/29/ -> номерная сборка 29
# https://smart-updown.binom.pw/sol/ -> именованная сборка `sol`
# https://smart-updown.binom.pw/29/Build/WebGL.data -> ассет сборки 29
#
# ⚠️ ПОЧЕМУ КОРЕНЬ РЕДИРЕКТИТ, А НЕ ОТДАЁТ ФАЙЛЫ:
# index.html сборки ссылается на ассеты ОТНОСИТЕЛЬНЫМ путём (`buildUrl = "Build"`).
# Если отдавать его прямо с корня, ассеты запрашиваются как /Build/WebGL.wasm — БЕЗ номера
# сборки. Такой URL между релизами НЕ меняется, а мы отдаём его `immutable` на 7 суток →
# браузер игрока неделю держит ассеты старой сборки и игнорирует новый билд (мина из ADR-010).
# При редиректе на /<N>/ все ассеты получают версионированный URL (/29/Build/...), старый URL
# просто перестаёт использоваться, и `immutable` становится корректным.
# Номер активной сборки пишет publish-release.sh в отдельный include-файл /etc/nginx/game-active.inc.
#
# ⚠️ ПОРЯДОК LOCATION. Служебные пути (/api, /ws, /solana-rpc) объявлены с префиксом `^~`,
# потому что regex-локейшн сборок `^/(?<build>…)` иначе перехватил бы их (regex в nginx
# приоритетнее обычного префикса). `^~` подавляет проверку regex для этого префикса.
#
# 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.
# Всё остальное (включая именованные сборки: их папку могут перезалить) -> no-store.
map $uri $game_cache_control {
default "no-store";
~^/[0-9]+/.+\.(js|wasm|data|mem|symbols|css|png|jpg|jpeg|gif|svg|woff2?|unityweb)$ "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;
# --- страховка: API (^~ — приоритетнее regex-локейшна сборок) -------------
# Нормальный /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;
}
# --- сборки: /<N>/... и /<имя>/... ---------------------------------------
# /29/index.html -> /opt/game/releases/29/index.html
# /sol/index.html -> /opt/game/releases/sol/index.html
# /29/Build/WebGL.data -> /opt/game/releases/29/Build/WebGL.data
location ~ ^/(?<build>[a-zA-Z0-9][a-zA-Z0-9_-]*)(?<subpath>/.*)?$ {
root /opt/game/releases;
try_files /$build$subpath /$build$subpath/ =404;
}
}