0
0
NginxHow-ToBeginner · 3 min read

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 the Upgrade header 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; and proxy_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

DirectivePurpose
proxy_passForward requests to backend WebSocket server
proxy_http_version 1.1Use HTTP/1.1 for WebSocket support
proxy_set_header Upgrade $http_upgradeForward Upgrade header for handshake
proxy_set_header Connection "upgrade"Tell server to switch protocols
proxy_set_header Host $hostPreserve original Host header
proxy_read_timeoutIncrease 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.