# FluentGerman.ai — Nginx Configuration Template # Copy to /etc/nginx/sites-available/fluentgerman and adjust values marked with <...> # # Setup steps: # 1. sudo cp deploy/nginx.conf.example /etc/nginx/sites-available/fluentgerman # 2. Edit the file: replace and # 3. sudo ln -sf /etc/nginx/sites-available/fluentgerman /etc/nginx/sites-enabled/ # 4. sudo nginx -t && sudo systemctl reload nginx # 5. Install SSL: sudo certbot --nginx -d server { listen 80; server_name fluentgerman.mydomain.io; # ← Replace with your subdomain # Redirect HTTP → HTTPS (uncomment after certbot setup) # return 301 https://$host$request_uri; # ── Frontend static files ────────────────────────────────────── root /opt/fluentgerman/frontend; index index.html; location / { try_files $uri $uri/ /index.html; } # ── API reverse proxy ────────────────────────────────────────── location /api/ { proxy_pass http://127.0.0.1:8999; # ← Must match APP_PORT in .env 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 Connection ''; # SSE support (critical for chat streaming) proxy_buffering off; proxy_cache off; proxy_read_timeout 300s; chunked_transfer_encoding on; } # ── Security headers ─────────────────────────────────────────── 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; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # ── Performance ──────────────────────────────────────────────── gzip on; gzip_types text/plain text/css application/json application/javascript text/xml; gzip_min_length 256; gzip_vary on; # Upload size limit (voice audio files) client_max_body_size 25M; # Static file caching location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff2?)$ { expires 7d; add_header Cache-Control "public, immutable"; } } # ── HTTPS block (auto-generated by certbot, shown for reference) ─── # server { # listen 443 ssl http2; # server_name fluentgerman.mydomain.io; # # ssl_certificate /etc/letsencrypt/live/fluentgerman.mydomain.io/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/fluentgerman.mydomain.io/privkey.pem; # include /etc/letsencrypt/options-ssl-nginx.conf; # ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # # # ... (same location blocks as above) # }