Nginx WebSocketプロキシ設定

NginxでWebSocket接続を適切なHTTP Upgradeヘッダーでプロキシする設定方法を解説。タイムアウト調整、接続の永続化、SSL WSS対応も含みます。

Proxy

詳細な説明

WebSocket接続はHTTP Upgradeメカニズムを使用して標準HTTPリクエストから永続的な双方向通信チャネルに切り替えるため、Nginxで特別な処理が必要です。

基本的なWebSocketプロキシ

重要なのは、UpgradeConnection ヘッダーをクライアントからバックエンドサーバーに渡すことです:

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

HTTP/1.1が必要な理由

WebSocket接続はHTTP/1.1の Upgrade メカニズムに依存しています。Nginxはデフォルトでアップストリーム接続にHTTP/1.0を使用しますが、HTTP/1.0は接続のアップグレードをサポートしていません。そのため proxy_http_version 1.1 ディレクティブはWebSocketプロキシの動作に必須です。

タイムアウト設定

WebSocket接続は本質的に長時間維持されますが、Nginxはデフォルトで60秒後にアイドル接続を閉じます。アクティブなWebSocketセッションの早期切断を防ぐため、readおよびsendのタイムアウトを延長します:

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

または、アプリケーションレベルのping/pongフレームを定期的に送信して接続を維持する方法もあります。

HTTPとWebSocketトラフィックの両方の処理

多くのアプリケーションは同じポートでHTTPとWebSocketの両方のトラフィックを処理します。map ディレクティブを使用して、リクエストにUpgradeヘッダーが含まれるかどうかでConnectionヘッダーを条件付きに設定します:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}

server {
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

WebSocketのロードバランシング

複数のバックエンドでWebSocket接続をロードバランシングする場合、ip_hash を使用してクライアントが常に同じバックエンドサーバーに接続されるようにします。WebSocketの状態は通常、特定のサーバーインスタンスのメモリに保持され、クラスター間で共有されないためです。

SSL WebSocket(WSS)

セキュアなWebSocket接続では、Nginx層でSSLを終端し、内部的には暗号化なしのバックエンドにプロキシします。クライアントは wss:// でNginxに接続し、NginxがTLS復号を処理して ws:// としてバックエンドに転送することで、証明書管理を簡素化します。

ユースケース

リアルタイムチャットアプリケーションやライブ通知システムをデプロイし、WebSocket接続をNginxを通じてバックエンドに適切にプロキシする必要があります。

Try It — Nginx Config Generator

フルツールを開く