# HOA LedgerIQ — Host-level nginx config (production) # # Copy this file to /etc/nginx/sites-available/app.yourdomain.com # and symlink to /etc/nginx/sites-enabled/: # # sudo cp nginx/host-production.conf /etc/nginx/sites-available/app.yourdomain.com # sudo ln -s /etc/nginx/sites-available/app.yourdomain.com /etc/nginx/sites-enabled/ # sudo nginx -t && sudo systemctl reload nginx # # Then obtain an SSL certificate: # sudo certbot --nginx -d app.yourdomain.com # # Replace "app.yourdomain.com" with your actual hostname throughout this file. # --- Rate limiting --- # 10 requests/sec per IP for API routes (shared memory zone: 10 MB ≈ 160k IPs) limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; # --- HTTP → HTTPS redirect --- server { listen 80; server_name app.yourdomain.com; # Let certbot answer ACME challenges location /.well-known/acme-challenge/ { root /var/www/certbot; } # Everything else → HTTPS location / { return 301 https://$host$request_uri; } } # --- Main HTTPS server --- server { listen 443 ssl; server_name app.yourdomain.com; # SSL certificates (managed by certbot) ssl_certificate /etc/letsencrypt/live/app.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/app.yourdomain.com/privkey.pem; # Modern TLS settings ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # --- Proxy defaults --- proxy_http_version 1.1; 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 Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Buffer settings — prevent 502s when backend is slow to respond proxy_buffering on; proxy_buffer_size 16k; proxy_buffers 8 16k; proxy_busy_buffers_size 32k; # --- API routes → NestJS backend (port 3000) --- location /api/ { limit_req zone=api_limit burst=30 nodelay; proxy_pass http://127.0.0.1:3000; proxy_read_timeout 30s; proxy_connect_timeout 5s; proxy_send_timeout 15s; } # AI endpoints now return immediately (async processing in background) # No special timeout overrides needed # --- Frontend → React SPA served by nginx (port 3001) --- location / { proxy_pass http://127.0.0.1:3001; proxy_read_timeout 10s; proxy_connect_timeout 5s; proxy_cache_bypass $http_upgrade; } }