configs/nginx.conf

225 lines
9.3 KiB
Nginx Configuration File
Raw Permalink 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.

upstream backend_app {
server 127.0.0.1:13200;
keepalive 32;
}
upstream frontend_web {
server 127.0.0.1:13300;
keepalive 16;
}
upstream tusd_backend {
server 127.0.0.1:13400;
keepalive 16;
}
# Access log format including request id
log_format reqid '$time_iso8601 [$req_id] $remote_addr "$request" $status $body_bytes_sent $request_time "$http_referer" "$http_user_agent"';
# Correlate/propagate request id; if client sent X-Request-Id use it, otherwise generate
map $http_x_request_id $req_id {
default $http_x_request_id;
"" $request_id;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# CORS: reflect Origin if present (fixes credentials-mode restriction)
# If no Origin header -> do not send A-C-A-Origin
map $http_origin $cors_origin {
"" "";
~^https?://[^/]+$ $http_origin;
}
server {
listen 80;
server_name my-public-node-103.projscale.dev;
# Emit request id even on redirects
add_header X-Request-Id $req_id always;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name my-public-node-103.projscale.dev;
# Access log with request id
access_log /var/log/nginx/access.log reqid;
# SSL configuration (valid certs)
ssl_certificate /etc/letsencrypt/live/my-public-node-103.projscale.dev/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-public-node-103.projscale.dev/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Общие параметры для стабильности и больших файлов
client_max_body_size 10G;
client_body_timeout 300s;
client_header_timeout 300s;
keepalive_timeout 65s;
# Сжатие текстовых ответов
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
# Безопасные заголовки (минимальный набор) и корреляция
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header X-Request-Id $req_id always;
# CORS: apply globally; specific locations may add extra Expose/Allow lists
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD" always;
add_header Access-Control-Allow-Headers "Origin, Cache-Control, Content-Type, Accept, Authorization, Referer, User-Agent, Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, Tus-Resumable, tus-resumable, Upload-Length, upload-length, Upload-Offset, upload-offset, Upload-Metadata, upload-metadata, Upload-Defer-Length, upload-defer-length, Upload-Concat, upload-concat, x-file-name, x-last-chunk, x-chunk-start, x-upload-id, x-request-id" always;
add_header Vary "Origin" always;
# Статика фронтенда (SPA)
location / {
proxy_pass http://frontend_web;
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 $req_id;
proxy_read_timeout 60s;
}
# Агрессивное кеширование хешированных ассетов (Vite кладет их в /assets)
location ^~ /assets/ {
proxy_pass http://frontend_web;
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 $req_id;
proxy_read_timeout 60s;
proxy_hide_header Cache-Control;
add_header Cache-Control "public, max-age=31536000, immutable" always;
}
location = /tus {
return 308 /tus/;
}
location /tus/ {
# Proxy uploads to tusd with resumable-friendly settings
proxy_pass http://tusd_backend/;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off;
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
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 $req_id;
# CORS for tus
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PATCH, HEAD, OPTIONS" always;
add_header Access-Control-Allow-Headers "Origin, Cache-Control, Content-Type, Accept, Authorization, Referer, User-Agent, Tus-Resumable, Upload-Length, Upload-Offset, Upload-Metadata, Upload-Defer-Length, Upload-Concat" always;
add_header Access-Control-Expose-Headers "Location, Upload-Offset, Tus-Version, Tus-Resumable, Tus-Max-Size, Tus-Extension" always;
add_header Vary "Origin" always;
if ($request_method = OPTIONS) { return 204; }
}
location = /files {
return 308 /files/;
}
location /files/ {
# Direct file access through tusd (GET/HEAD support, resumable resume)
proxy_pass http://tusd_backend;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off;
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
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 $req_id;
# CORS for file GET/HEAD
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always;
add_header Access-Control-Allow-Headers "Origin, Cache-Control, Content-Type, Accept, Authorization, Referer, User-Agent" always;
add_header Access-Control-Expose-Headers "Location, Upload-Offset, Tus-Version, Tus-Resumable, Tus-Max-Size, Tus-Extension" always;
add_header Vary "Origin" always;
if ($request_method = OPTIONS) { return 204; }
}
# API
location /api/ {
proxy_pass http://backend_app;
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 $req_id;
# Для chunked uploads и стриминга не буферизуем запрос/ответ
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_buffering off;
proxy_max_temp_file_size 0;
proxy_set_header Connection "";
# Таймауты для больших файлов
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# CORS for API
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD" always;
add_header Access-Control-Allow-Headers "Origin, Cache-Control, Content-Type, Accept, Authorization, Referer, User-Agent, Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site, x-admin-token, Tus-Resumable, tus-resumable, Upload-Length, upload-length, Upload-Offset, upload-offset, Upload-Metadata, upload-metadata, Upload-Defer-Length, upload-defer-length, Upload-Concat, upload-concat, x-file-name, x-last-chunk, x-chunk-start, x-upload-id, x-request-id" always;
add_header Vary "Origin" always;
# Вебсокеты (на будущее)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
if ($request_method = OPTIONS) { return 204; }
}
# Health to backend
location = /health {
proxy_pass http://backend_app/api/system.version;
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 $req_id;
}
}