nginxによるsocket.ioプロキシの設定

socket.ionginx のインストールと設定 - koba::blognginx を導入した目的は、WebSocketを使用したWebアプリを提供することであった。なので今回は実際に socket.io を使用した 簡単なWebアプリ にリバースプロキシからアクセスしてみた。

設定例

location /chat/ {
    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_redirect http://127.0.0.1:3000/ https://kobalab.net/chat/;
    proxy_redirect / /chat/;

    proxy_cookie_path / /chat;
}

設定項目

location
proxyに割り当てる nginx 側のパス。/chat/ とした。
proxy_pass
proxyのアクセス先のURL。/ で終端させるとリクエストURIを /chat// に変換してアクセスするようになる。*1
proxy_http_version
使用するHTTPプロトコルのバージョン。1.1 以降でないとWebSocketをサポートしていない。
proxy_set_header
ハンドシェイク時にproxyが送信するネゴシエーションヘッダ。この通り設定すればOK。
proxy_redirect
ステータスコード 3xx のリダイレクト応答があった場合の Location ヘッダの書き換え方法*2
http:// ではじまる完全URLと、/ ではじまる絶対パスについて記述するとよい。
proxy_cookie_path
応答に Set-Cookie ヘッダがあった場合の path の書き換え方法*3

注意事項

socket.io のプログラム例では接続の際に

    let socket = io(); 

としているが、プロキシがパスを変更する場合はこれでは動作しない*4。以下のような修正が必要*5

    let socket = io("/", { path: location.pathname + 'socket.io/' });

*1:/ で終端しない場合は /chat のままアクセスするので 404 Not Found となってしまう

*2:Apacheの ProxyPassReverse 相当

*3:Apacheの ProxyPassReverseCookiePath 相当

*4:特に指定がない場合、socket.io は /socket.io/ でハンドシェイクするが、今回の構成では /chat/socket.io/ がハンドシェイクのパスとなるため

*5:第1引数はアプリケーションの都合で決めてください。デフォルト値は /