# Multi-Tenant Nginx Configuration # Supports wildcard SSL and subdomain-based tenant routing # Rate limiting zones limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/s; # Upstream backend upstream backend { server backend:3001; } # HTTP redirect to HTTPS server { listen 80; server_name dev.uggla.uamils.com *.dev.uggla.uamils.com; # Let's Encrypt challenge location /.well-known/acme-challenge/ { root /var/www/certbot; } # Redirect all other traffic to HTTPS location / { return 301 https://$host$request_uri; } } # Main HTTPS server for multi-tenant setup server { listen 443 ssl http2; server_name dev.uggla.uamils.com *.dev.uggla.uamils.com; # SSL Configuration ssl_certificate /etc/letsencrypt/live/dev.uggla.uamils.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dev.uggla.uamils.com/privkey.pem; # SSL Security ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # Security Headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options DENY always; add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Client settings client_max_body_size 100M; # Extract tenant from subdomain set $tenant "default"; if ($host ~ ^([^.]+)\.dev\.uggla\.uamils\.com$) { set $tenant $1; } # API routes with rate limiting location /api/ { limit_req zone=api burst=20 nodelay; # Add tenant header for backend proxy_set_header X-Tenant-Subdomain $tenant; 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-Forwarded-Port $server_port; proxy_pass http://backend; proxy_redirect off; # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # Upload routes for logos and other files location /uploads/ { # Add tenant header for backend proxy_set_header X-Tenant-Subdomain $tenant; 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-Forwarded-Port $server_port; proxy_pass http://backend; proxy_redirect off; # Cache uploaded files for 1 month proxy_cache_valid 200 30d; add_header Cache-Control "public, max-age=2592000"; # Timeouts proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # Authentication routes with stricter rate limiting location /auth/ { limit_req zone=auth burst=10 nodelay; proxy_set_header X-Tenant-Subdomain $tenant; 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_pass http://backend; proxy_redirect off; } # Socket.IO with WebSocket support location /ws { proxy_set_header X-Tenant-Subdomain $tenant; 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; # WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://backend; proxy_redirect off; # WebSocket timeouts proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } # Static files (React app) location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; # Cache static assets location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # Add tenant info to HTML location = /index.html { add_header X-Tenant-Subdomain $tenant always; expires 0; add_header Cache-Control "no-cache, no-store, must-revalidate"; } } # Health check location /nginx-health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } } # Specific configuration for main domain (app subdomain) server { listen 443 ssl http2; server_name app.dev.uggla.uamils.com; # SSL Configuration (same as above) ssl_certificate /etc/letsencrypt/live/dev.uggla.uamils.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dev.uggla.uamils.com/privkey.pem; # Include all the same configurations as above include /etc/nginx/conf.d/common-ssl.conf; # Set default tenant set $tenant "app"; # Include common proxy configurations include /etc/nginx/conf.d/common-proxy.conf; }