| worker_processes auto; | |
| events { | |
| worker_connections 1024; | |
| } | |
| http { | |
| resolver 127.0.0.11 valid=10s; | |
| # Define a rate limit zone to prevent abuse | |
| limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; | |
| # Map Authorization header to a token variable for sticky sessions | |
| map $http_authorization $auth_token { | |
| "~*Bearer\s+(.*)" $1; | |
| default $remote_addr; # Fallback to IP hash if no token is provided | |
| } | |
| # Upstream with hash-based load balancing (Sticky Sessions) | |
| # The hash uses the user's API Key so the same API Key always hits the same node, | |
| # preserving the cascade_id context in memory. | |
| upstream windsurf_backend { | |
| hash $auth_token consistent; | |
| # In a real Swarm/Compose environment with scale=3, Docker DNS resolves 'windsurf-api' to all IPs. | |
| # But 'hash' works better with explicit servers or using a DNS resolver dynamically if needed. | |
| # Nginx free version requires manual IP listings for sticky sessions, | |
| # or we rely on ip_hash for generic load balancing if behind a single reverse proxy. | |
| zone windsurf_backend_zone 64k; | |
| server windsurf-api:3003 resolve; | |
| } | |
| server { | |
| listen 80; | |
| location / { | |
| limit_req zone=mylimit burst=20 nodelay; | |
| proxy_pass http://windsurf_backend; | |
| proxy_http_version 1.1; | |
| # SSE and streaming requirements | |
| proxy_set_header Connection ''; | |
| proxy_buffering off; | |
| proxy_cache off; | |
| chunked_transfer_encoding on; | |
| proxy_set_header Host $host; | |
| proxy_set_header X-Real-IP $remote_addr; | |
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
| } | |
| } | |
| } | |