ADR-011: статика игры вынесена из куба на nginx (LXC 152 game-web), версии каталогами

- корень smart-updown.binom.pw -> nginx на Proxmox (LXC 152, 192.168.76.152)
- /api,/ws -> куб (router PathPrefix на внешнем Traefik VDS), куб не менялся
- версионирование: /opt/game/releases/<N>/, активная = симлинк /opt/game/current
- tools/proxmox-nginx: unpack-release.sh, publish-release.sh, game.nginx.conf, smart-updown.traefik.yaml, README
- приёмка живьём: корень 200 nginx/1.24.0 (Ubuntu), /27/ /28/ 200, /api/state 200 JSON, /api/ws цена, autoclose-check 9/9
- питфоллы: OCI-manifest в skopeo dir-дампе, слэш в конце версии, /solana-rpc мимо PathPrefix /api
This commit is contained in:
Porfiry
2026-09-15 17:07:30 +03:00
parent 21a3a37a66
commit f105c1adff
8 changed files with 405 additions and 2 deletions
+98
View File
@@ -0,0 +1,98 @@
# nginx для раздачи Unity-сборок «Бинарной ракеты» — LXC 152 (game-web, 192.168.76.152)
# Файл: /etc/nginx/sites-available/game
#
# Модель версионирования:
# /opt/game/releases/<N>/ — файлы сборки N (Build/, TemplateData/, index.html)
# /opt/game/current -> releases/<N> — активная сборка (симлинк, переключает publish-release.sh)
#
# https://smart-updown.binom.pw/ -> активная сборка (current)
# https://smart-updown.binom.pw/28/ -> конкретная сборка 28
# https://smart-updown.binom.pw/28/Build/WebGL.data -> ассет сборки 28
#
# 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";
~^/.+\.(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;
# --- версионированные сборки: /<число>/... -------------------------------
# /28/index.html -> /opt/game/releases/28/index.html
location ~ ^/(?<build>[0-9]+)(?<subpath>/.*)?$ {
root /opt/game/releases;
try_files /$build$subpath /$build$subpath/ =404;
}
# --- ассеты активной сборки ----------------------------------------------
location ~* \.(js|wasm|data|mem|symbols|json|css|png|jpg|jpeg|gif|svg|woff2?)$ {
root /opt/game/current;
try_files $uri =404;
}
# --- страховка: API -------------------------------------------------------
# Нормальный /api идёт мимо nginx (Traefik VDS -> куб). Если запрос всё же
# пришёл сюда — уходим в куб на k3s-Traefik с правильным Host, дальше
# ingress smart-updown-api ведёт в шлюз :8895.
location /api {
proxy_pass http://192.168.76.120;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 10s;
proxy_read_timeout 90s;
}
# страховка: WebSocket шлюза
location /ws {
proxy_pass http://192.168.76.120;
proxy_http_version 1.1;
proxy_set_header Host smart-updown.binom.pw;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
# страховка: тонкий CORS-прокси до Solana RPC (старые сборки игры)
location /solana-rpc/ {
proxy_pass http://192.168.76.181:8899/;
proxy_http_version 1.1;
proxy_set_header Host 192.168.76.181:8899;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Headers "content-type" always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
if ($request_method = OPTIONS) { return 204; }
}
# --- корень = активная сборка --------------------------------------------
location / {
try_files $uri $uri/ /index.html;
}
}