19
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DockerでnginxでwebSocket

Last updated at Posted at 2017-06-18

#DockerでnginxでwebSocket

dockerのnginx環境でwebSocket接続しようと思ったときハマったので共有します。
同じ悩みの方のヒントになれば幸いです。
なおここでは後述でのdocker-composeの使い方については省略します。

前準備

  1. dockerhubから通常インストール
    https://hub.docker.com/_/nginx/

  2. nginxのdefault.confを作成
    下記内容をコンテナ側ではなく親の方にファイル名mysite.templateで保存し、後述の方法でコンテナに読み込ませる

# For WebSocket

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    location /ws/ {
        proxy_pass http://(ws通信したいコンテナ名)/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

下記記述のところがwebSocket接続させるための記述

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

上記内容をファイル名mysite.templateで保存

dockerでnginx環境を設定する(失敗例)

  1. docker-compose.xmlで設定
    下記のような感じでmysite.templateをコンテナに読み込ませる感じで記述
version: '2'
services:
    proxy:
        restart: always
        image: nginx
        container_name: nginx_proxy
        volumes:
         - ./mysite.template:/etc/nginx/conf.d/mysite.template
        ports:
         - "80:80"
        command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

environmentの記述のところでenvsubstコマンドを使ってテンプレートとして読み込ませる
2. docker-composeを実行

docker-compose up -d proxy

…とするとエラーで起動しない。。
3. コンテナ内のdefault.confを確認

docker exec -it nginx_proxy bash

(コンテナ内)

cat /etc/nginx/conf.d/default.conf

おそらく下記のような記述になっているはず

…(略)…
proxy_http_version 1.1;
        proxy_set_header Upgrade ;
        proxy_set_header Connection "upgrade";
…(略)…

($http_upgradeのところが消えてる。。)

と、ここにヒントが。
http://kiririmode.hatenablog.jp/entry/20150908/1441711463

単に$...で記述するとテンプレート変数として扱われてしまうenvsubstの仕様ですね。
ということで、何らかのダミー変数を定義して渡せば$...の記述もそのまま反映させることができそうです。

dockerでnginx環境を設定する(成功例)

  1. docker-compose.xmlで設定
    下記のような感じでmysite.templateをコンテナに読み込ませる感じで記述
version: '2'
services:
    proxy:
        restart: always
        image: nginx
        container_name: nginx_proxy
        volumes:
         - ./mysite.template:/etc/nginx/conf.d/mysite.template
        ports:
         - "80:80"
         environment:
         - DUMMY=dummy
        command: /bin/bash -c "envsubst '$$DUMMY' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

(変更点)

  • environmentでダミー変数(DUMMY)を定義
  • commandのenvsubstで定義した変数を渡す
  1. docker-composeを実行
docker-compose up -d proxy

エラーなく実行できた!

あとは通常のwebSocket記述でクライアントから接続すれば応答するはずです。

wssでの接続

wssの場合でも特殊な設定は不要です。通常のssl記述のところにwebSocket用記述を追加するだけです。

  • docker-compose.xml
version: '2'
services:
    proxy:
        restart: always
        image: nginx
        container_name: nginx_proxy
        volumes:
         - ./mysite.template:/etc/nginx/conf.d/mysite.template
        ports:
         - "80:80"
         - "443:443"
        environment:
         - DUMMY=dummy
        command: /bin/bash -c "envsubst "envsubst '$$DUMMY' < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"

-mysite.template

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    ssl on;
    ssl_certificate (中間証明書のパス)/fullchain.pem;
    ssl_certificate_key (中間証明書のパス)/privkey.pem;

    server_name (ドメイン名);

    location /ws/ {
        proxy_pass http://(wss通信したいコンテナ名)/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
19
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?