Files
Genarrative/deploy/container/nginx.conf
T
suzmii eeb101458a
Project CI / Backend tests (pull_request) Failing after 34s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m27s
Project CI / Native shell tests (pull_request) Failing after 2m46s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m58s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m23s
Project CI / AI game creator shell web tests (pull_request) Failing after 45s
Project CI / Frontend tests (pull_request) Successful in 2m24s
Project CI / Repository checks (pull_request) Failing after 1m1s
Merge remote-tracking branch 'origin/master' into feat/game-fork
# Conflicts:
#	apps/ai-game-creator-shell/src-tauri/src/game_distribution_publish.rs
#	apps/ai-game-creator-shell/src/components/game-distribution/GameDistributionPublishPanel.tsx
#	apps/ai-game-creator-shell/tests/gameDistributionPublishPanel.test.tsx
#	docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md
#	package.json
#	packages/shared/src/contracts/gameDistribution.ts
#	scripts/check-game-distribution-dto-parity.mjs
#	server-rs/crates/api-server/src/modules/game_distribution.rs
#	server-rs/crates/module-game-distribution/src/errors.rs
#	server-rs/crates/module-game-distribution/src/lib.rs
#	server-rs/crates/shared-contracts/src/game_distribution.rs
#	server-rs/crates/spacetime-client/src/active.rs
#	server-rs/crates/spacetime-client/src/active/mapper.rs
#	server-rs/crates/spacetime-client/src/active/mapper/game_distribution.rs
#	server-rs/crates/spacetime-client/src/game_distribution.rs
#	server-rs/crates/spacetime-client/src/module_bindings.rs
#	server-rs/crates/spacetime-client/src/module_bindings/game_distribution_game_snapshot_type.rs
#	server-rs/crates/spacetime-client/src/module_bindings/game_distribution_game_type.rs
#	server-rs/crates/spacetime-module/src/game_distribution.rs
#	server-rs/crates/spacetime-module/src/migration.rs
#	src/components/game-distribution/GameDetailPage.tsx
#	src/components/game-distribution/GameDistributionPages.test.tsx
#	src/components/game-distribution/GamePlayPage.tsx
#	src/components/platform-entry/PlatformEntryActiveFlowShell.tsx
#	src/services/gameDistributionClient.test.ts
#	src/services/gameDistributionClient.ts
2026-10-06 16:10:52 +08:00

201 lines
7.4 KiB
Nginx Configuration File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
worker_processes auto;
events {
worker_connections 768;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format genarrative_upstream
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'request_time=$request_time upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time upstream_response_time=$upstream_response_time '
'upstream_status=$upstream_status request_id=$request_id';
upstream genarrative_api {
server api-server:8082;
keepalive 64;
}
limit_conn_zone $binary_remote_addr zone=genarrative_api_conn:10m;
limit_req_zone $binary_remote_addr zone=genarrative_api_rps:10m rate=300r/s;
limit_req_zone $binary_remote_addr zone=genarrative_admin_rps:10m rate=30r/s;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
application/xml+rss
image/svg+xml;
server {
listen 80;
server_name _;
access_log /var/log/nginx/genarrative.access.log genarrative_upstream;
error_log /var/log/nginx/genarrative.error.log warn;
limit_conn_status 429;
limit_conn_log_level warn;
limit_req_status 429;
limit_req_log_level warn;
root /srv/genarrative/web;
index index.html;
location ^~ /admin/api/ {
default_type application/json;
limit_conn genarrative_api_conn 64;
limit_req zone=genarrative_admin_rps burst=16 nodelay;
proxy_pass http://genarrative_api/admin/api/;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
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 $scheme;
proxy_set_header X-Request-Id $request_id;
}
location = /admin {
return 301 /admin/;
}
location ^~ /admin/assets/ {
try_files $uri =404;
}
location ^~ /admin/ {
try_files $uri $uri/ /admin/index.html;
}
location ^~ /assets/ {
try_files $uri =404;
}
# 平台付费游戏播放会话入口:`/api/game-distribution/play-sessions/<token>/…` 是 sandbox iframe
# 的 src,包内相对资源沿同一前缀解析。它与通用 `/api` 同口径代理到 api-server,唯一差别是
# 清空 Cookie:播放会话不读账号凭证,而 api-server 播放网关对带平台 refresh Cookie 的请求返回 403。
# 前缀 location 必须写 `^~`:不加时正则 location `~ ^/api(?:/|$)` 会先命中,Cookie 又会被转发。
location ^~ /api/game-distribution/play-sessions/ {
default_type application/json;
client_max_body_size 210m;
limit_conn genarrative_api_conn 64;
limit_req zone=genarrative_api_rps burst=64 nodelay;
proxy_pass http://genarrative_api;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
add_header X-Accel-Buffering no always;
proxy_set_header Connection "";
proxy_set_header Host $host;
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 $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-Id $request_id;
proxy_set_header Cookie "";
}
location ~ ^/api(?:/|$) {
default_type application/json;
# 中文注释:创作接口会携带参考图 Data URL,游戏发行包 PUT 更大,Nginx 只负责放行到 api-server;
# 真实大小限制仍由路由 DefaultBodyLimit(发行包 200 MiB + 1 KiB)和业务字节校验负责。
client_max_body_size 210m;
limit_conn genarrative_api_conn 64;
limit_req zone=genarrative_api_rps burst=64 nodelay;
proxy_pass http://genarrative_api;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
add_header X-Accel-Buffering no always;
proxy_set_header Connection "";
proxy_set_header Host $host;
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 $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Request-Id $request_id;
}
location ~ ^/(generated-|healthz|readyz) {
return 404;
}
location ~ ^/v1/database/[^/]+/subscribe$ {
proxy_pass http://spacetimedb:3101;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
}
location ^~ /v1/identity {
proxy_pass http://spacetimedb:3101;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location ^~ /v1/ {
return 404;
}
# 平台同源路径发行入口:/games/<gameId>/ 与 /games/<gameId>/<asset> 映射到
# api-server 发行网关。游戏文档跑在 iframe sandbox="allow-scripts" 的不透明来源里,
# 离开页面即随 iframe 卸载,因此不再要求独立发行域名与通配证书。
location ~ "^/games/(?<game_id>game_[0-9a-f]{32})(?<game_path>/.*)?$" {
proxy_http_version 1.1;
proxy_set_header Host $host;
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 $scheme;
proxy_set_header X-Request-Id $request_id;
proxy_set_header Cookie "";
proxy_pass http://genarrative_api/api/game-distribution/releases/$game_id$game_path;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
# BEGIN GENARRATIVE MAIN SPA ROUTES
location = / {
try_files /index.html =404;
}
location ~* "^/(?:creation|editor/canvas|pay|profile|profile/payment|project|components|design-system|creators|creators/connections|games|games/compare|games/detail|games/lineage|games/mine|games/play|games/publish|games/theme|games/themes)/?$" {
try_files $uri /index.html =404;
}
# 收银台深链 `/pay/<checkoutToken>`:只放行裸前缀会让真实收银台链接落到默认 location 变 404。
location ~* "^/pay/[^/]+/?$" {
try_files $uri /index.html =404;
}
# END GENARRATIVE MAIN SPA ROUTES
location / {
try_files $uri $uri/ =404;
}
}
}