How to Proxy WebSocket Connections with Nginx
To proxy WebSocket connections with
nginx, use the proxy_pass directive along with headers Upgrade and Connection set to upgrade. This ensures the WebSocket handshake is properly forwarded to the backend server.Syntax
The basic syntax to proxy WebSocket in nginx involves setting the proxy_pass to your backend WebSocket server and adding headers to handle the WebSocket handshake:
proxy_set_header Upgrade $http_upgrade;forwards theUpgradeheader from the client.proxy_set_header Connection "upgrade";tells the server to switch protocols.proxy_http_version 1.1;ensures HTTP/1.1 is used, which supports WebSocket.
nginx
location /ws/ {
proxy_pass http://backend_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}Example
This example shows a complete nginx server block that proxies WebSocket requests from /ws/ to a backend WebSocket server running on http://localhost:8080. It includes necessary headers and HTTP version settings.
nginx
server {
listen 80;
server_name example.com;
location /ws/ {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
location / {
proxy_pass http://localhost:3000;
}
}Output
Nginx starts successfully and proxies WebSocket connections from ws://example.com/ws/ to ws://localhost:8080/
Common Pitfalls
Common mistakes when proxying WebSocket with nginx include:
- Not setting
proxy_http_version 1.1;, which breaks the WebSocket handshake. - Omitting
proxy_set_header Upgrade $http_upgrade;andproxy_set_header Connection "upgrade";, causing the connection to not upgrade. - Using HTTP/2 for proxying WebSocket, which is not supported.
- Not increasing
proxy_read_timeout, leading to premature connection closure.
Wrong example:
location /ws/ {
proxy_pass http://backend_server;
# Missing upgrade headers and HTTP version
}Correct example:
location /ws/ {
proxy_pass http://backend_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}Quick Reference
| Directive | Purpose |
|---|---|
| proxy_pass | Forward requests to backend WebSocket server |
| proxy_http_version 1.1 | Use HTTP/1.1 for WebSocket support |
| proxy_set_header Upgrade $http_upgrade | Forward Upgrade header for handshake |
| proxy_set_header Connection "upgrade" | Tell server to switch protocols |
| proxy_set_header Host $host | Preserve original Host header |
| proxy_read_timeout | Increase timeout to keep connection alive |
Key Takeaways
Always set proxy_http_version to 1.1 when proxying WebSocket in nginx.
Include proxy_set_header Upgrade and Connection headers to enable protocol upgrade.
Do not use HTTP/2 for WebSocket proxying as it is unsupported.
Increase proxy_read_timeout to prevent WebSocket connection drops.
Test your configuration by connecting through nginx to ensure the handshake succeeds.