{ admin off auto_https off persist_config off log { format json output stdout level INFO } servers { protocols h1 h2 h2c timeouts { read_body 10s read_header 10s write 30s idle 120s } } } # Listen on Railway's PORT or default to 3000 :{$PORT:3000} { # Security headers header { # HSTS (only in production with HTTPS) Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Prevent clickjacking X-Frame-Options "SAMEORIGIN" # XSS Protection X-Content-Type-Options "nosniff" X-XSS-Protection "1; mode=block" # Referrer policy Referrer-Policy "strict-origin-when-cross-origin" # Content Security Policy (adjust as needed) Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https:;" # Permissions policy Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=()" # Remove server identification -Server -X-Powered-By } handle /admin* { reverse_proxy localhost:5001 { header_up Host {host} header_up X-Real-IP {remote_host} transport http { read_timeout 60s write_timeout 60s } } } handle { reverse_proxy localhost:5000 { header_up Host {host} header_up X-Real-IP {remote_host} transport http { read_timeout 30s write_timeout 30s } } } # Error handling handle_errors { @5xx expression `{http.error.status_code} >= 500` handle @5xx { respond "Service temporarily unavailable" 503 { close } } respond "{http.error.status_code} {http.error.status_text}" { close } } }