How to configure WebSocket proxy in Nginx?
WebSocket is a protocol that provides full-duplex communication over a single TCP connection. Nginx can act as a WebSocket proxy, forwarding client WebSocket connections to backend servers.
Basic Configuration:
nginxmap $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name example.com; location /ws { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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; # Timeout settings proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } }
Key Configuration Explanation:
- proxy_http_version 1.1: WebSocket requires HTTP/1.1 protocol
- Upgrade and Connection headers: Tell Nginx this is a WebSocket connection
- Timeout settings: WebSocket is a long connection, need to set longer timeout
Complete Configuration Example:
nginxhttp { upstream websocket_backend { server 192.168.1.100:8080; server 192.168.1.101:8080; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name example.com; # WebSocket proxy location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $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; # Timeout settings (adjust according to actual needs) proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; # Disable buffering proxy_buffering off; } # Regular requests location / { proxy_pass http://backend; proxy_set_header Host $host; } } }
HTTPS WebSocket Configuration:
nginxserver { listen 443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; } }
WebSocket Load Balancing:
nginxupstream websocket_backend { # Use ip_hash for session persistence ip_hash; server 192.168.1.100:8080; server 192.168.1.101:8080; server 192.168.1.102:8080; }
Important Notes:
- Session persistence: WebSocket connections need to stay on the same backend server, use ip_hash or sticky module
- Timeout settings: Set appropriate timeout according to business requirements
- Buffering: WebSocket real-time communication needs to disable buffering
- Firewall: Ensure firewall allows long connections
- Load balancing: Avoid using round-robin strategy, it will cause connection interruption
Performance Optimization:
nginx# Increase worker connections events { worker_connections 4096; } # Adjust keepalive upstream websocket_backend { server 192.168.1.100:8080; keepalive 32; } # TCP optimization location /ws { proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # TCP optimization proxy_socket_keepalive on; proxy_connect_timeout 60s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; }
Multi-path WebSocket:
nginx# Different paths forward to different backends location /chat/ws { proxy_pass http://chat_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } location /notification/ws { proxy_pass http://notification_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; }
Monitoring and Logging:
nginx# Custom log format log_format websocket '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; access_log /var/log/nginx/websocket_access.log websocket; # Monitor connection count location /nginx_status { stub_status on; access_log off; }
Troubleshooting:
- Connection drops: Check if timeout settings are reasonable
- Cannot connect: Check if Upgrade and Connection headers are correct
- Load balancing issues: Use ip_hash for session persistence
- Performance issues: Adjust worker_connections and buffer settings