events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; # Logging access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # Gzip gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; # File upload limit (15 MB) client_max_body_size 15M; # Rate limiting zones limit_req_zone $binary_remote_addr zone=api_auth:10m rate=10r/m; limit_req_zone $binary_remote_addr zone=api_general:10m rate=60r/m; upstream backend { server backend:8000; } upstream frontend { server frontend:80; } server { listen 80; server_name localhost; # Frontend location / { proxy_pass http://frontend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Auth API - strict rate limit (10 req/min with burst of 5) location /api/v1/auth { limit_req zone=api_auth burst=5 nodelay; limit_req_status 429; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Backend API - general rate limit (60 req/min with burst of 20) location /api { limit_req zone=api_general burst=20 nodelay; limit_req_status 429; proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Timeout for long GPT requests (15 min) proxy_read_timeout 900; proxy_connect_timeout 900; proxy_send_timeout 900; } # Static files (uploads) location /uploads { alias /app/uploads; expires 30d; add_header Cache-Control "public, immutable"; } # Health check location /health { proxy_pass http://backend; } } }