HxHippy

WebSocket Proxy

Proxying WebSocket connections through Nginx.

Last updated: 2025-01-15

Basic WebSocket Proxy

server {
    listen 80;
    server_name example.com;

    location /ws/ {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}

Connection Upgrade Map

# Handle both HTTP and WebSocket
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

Extended Timeouts

location /ws/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

    # Long timeouts for persistent connections
    proxy_read_timeout 86400s;
    proxy_send_timeout 86400s;

    # Disable buffering for real-time
    proxy_buffering off;
}

Socket.io Configuration

server {
    listen 443 ssl http2;
    server_name example.com;

    # Regular HTTP traffic
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # Socket.io specific path
    location /socket.io/ {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;

        # WebSocket headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Preserve headers
        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;

        # Long timeouts
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;

        # No buffering
        proxy_buffering off;
        proxy_cache off;
    }
}

Load Balanced WebSocket

upstream websocket {
    # IP hash for sticky sessions
    ip_hash;

    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    location /ws/ {
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;

        proxy_read_timeout 86400s;
    }
}

Secure WebSocket (WSS)

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # WSS is just WS over HTTPS
    location /wss/ {
        proxy_pass http://localhost:3000/ws/;
        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-Proto $scheme;

        proxy_read_timeout 86400s;
    }
}

Multiple WebSocket Endpoints

server {
    listen 443 ssl http2;
    server_name example.com;

    # Chat WebSocket
    location /ws/chat/ {
        proxy_pass http://chat-server:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
    }

    # Notifications WebSocket
    location /ws/notifications/ {
        proxy_pass http://notification-server:3002;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
    }

    # Live updates WebSocket
    location /ws/live/ {
        proxy_pass http://live-server:3003;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400s;
    }
}

Debugging WebSocket Issues

# Test WebSocket connection
curl -i -N -H "Connection: Upgrade" \
     -H "Upgrade: websocket" \
     -H "Sec-WebSocket-Key: test" \
     -H "Sec-WebSocket-Version: 13" \
     https://example.com/ws/

# Check nginx logs
tail -f /var/log/nginx/error.log | grep -i upgrade
intermediate Reverse Proxy Updated 2025-01-15
  • nginx
  • websocket
  • ws
  • wss
  • upgrade
  • real-time