{ # Global options - HTTP only (SSL терминируется на Synology) admin off http_port 80 } # API subdomain - проксирует на backend + MinIO S3 API api.{$DOMAIN} { # MinIO S3 API: /s3/* -> minio:9000 @s3 { path /s3/* } reverse_proxy @s3 minio:9000 { header_up Host {host} header_up X-Real-IP {remote} header_up X-Forwarded-For {remote} header_up X-Forwarded-Proto {scheme} } # Backend API: всё остальное -> backend:8080 reverse_proxy backend:8080 { header_up Host {host} header_up X-Real-IP {remote} header_up X-Forwarded-For {remote} header_up X-Forwarded-Proto {scheme} } # Security headers (HSTS на Synology, здесь — остальное) header { X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" Permissions-Policy "geolocation=(), microphone=(), camera=()" } # Rate limiting at proxy level (backup to app-level) @auth { path /api/v1/auth/* } rate_limit @auth { zone auth rate 10/minute key {remote} } } # Frontend main domain {$DOMAIN} { reverse_proxy frontend:3000 { header_up Host {host} header_up X-Real-IP {remote} header_up X-Forwarded-For {remote} header_up X-Forwarded-Proto {scheme} } # Security headers header { X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" Permissions-Policy "geolocation=(), microphone=(), camera=()" Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://api-maps.yandex.ru; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' wss: https://api.{$DOMAIN} https://api-maps.yandex.ru; frame-ancestors 'none';" } # Static assets caching @static { path /_next/static/* path /static/* path /images/* path /favicon.ico } header @static Cache-Control "public, max-age=31536000, immutable" # Compression encode zstd gzip } # MinIO Console (9001) — ТОЛЬКО внутри Docker сети, доступ через SSH туннель # Никакого внешнего доступа, никакого minio.{$DOMAIN}