# FetchML Nginx Site Configuration # Drop this file into /etc/nginx/sites-available/fetchml # Then: sudo ln -s /etc/nginx/sites-available/fetchml /etc/nginx/sites-enabled/ # Test: sudo nginx -t # Reload: sudo systemctl reload nginx server { listen 80; server_name ml.example.com; # CHANGE THIS to your domain # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name ml.example.com; # CHANGE THIS to your domain # SSL Configuration # CHANGE THESE paths to your actual SSL certificates ssl_certificate /etc/ssl/certs/ml.example.com.crt; ssl_certificate_key /etc/ssl/private/ml.example.com.key; # Modern SSL settings ssl_protocols TLSv1.3 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; # 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; # Hide nginx version server_tokens off; # Rate limiting for API limit_req_zone $binary_remote_addr zone=fetchml_api:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=fetchml_ws:10m rate=5r/s; # Client limits client_max_body_size 10M; client_body_timeout 12s; client_header_timeout 12s; # Logging access_log /var/log/nginx/fetchml_access.log; error_log /var/log/nginx/fetchml_error.log warn; # WebSocket endpoint location /ws { limit_req zone=fetchml_ws burst=10 nodelay; proxy_pass http://localhost:9102; # CHANGE PORT if needed proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; 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 timeouts proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } # API endpoints location /api/ { limit_req zone=fetchml_api burst=20 nodelay; proxy_pass http://localhost:9102; # CHANGE PORT if needed 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-API-Key $http_x_api_key; } # Health check location /health { proxy_pass http://localhost:9102; # CHANGE PORT if needed proxy_set_header Host $host; access_log off; } # Grafana (optional - only if you want to expose it) # Uncomment if you want Grafana accessible via nginx # location /grafana/ { # proxy_pass http://localhost:3000/; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # } }