LaraDock を使って Docker の Nginx にSSL設定を行って WebSocket でのアクセスを ws から wss で行えるようにする設定を行ったメモ


概要

LaraDockのNginxでwsのwss化が簡単にできそうなのでやってみる。

環境

前回のQuoridorn環境を引き続き使う。

ソース(クライアント)
ソース(サーバ)

サーバ側

nginxの準備

LaraDockのnginxのDockerフォルダを使う。

Dockerfileの修正

LaraDockはLaravel用なのでPHPの設定が入っている。
今回は使わないので消す。

virtual-environment/provision/docker/nignx/Dockerfile
FROM nginx:alpine

LABEL maintainer="Mahmoud Zalt <[email protected]>"

# // 省略

- # Set upstream conf and remove the default conf
-  RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \
-     && rm /etc/nginx/conf.d/default.conf

ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/\r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]

EXPOSE 80 443

設定の変更

フォルダ内のconfigファイルを以下のように修正する。

virtual-environment/provision/docker/nginx/sites/default.conf
@@ -1,32 +1,30 @@
+upstream websocket {
+    server node-server:8000;
+}
+
 server {

     listen 80 default_server;
     listen [::]:80 default_server ipv6only=on;

     # For https
-    # listen 443 ssl default_server;
-    # listen [::]:443 ssl default_server ipv6only=on;
-    # ssl_certificate /etc/nginx/ssl/default.crt;
-    # ssl_certificate_key /etc/nginx/ssl/default.key;
+    listen 443 ssl default_server;
+    listen [::]:443 ssl default_server ipv6only=on;
+    ssl_certificate /etc/nginx/ssl/default.crt;
+    ssl_certificate_key /etc/nginx/ssl/default.key;

     server_name localhost;
-    root /var/www/public;
-    index index.php index.html index.htm;


-    location / {
-         try_files $uri $uri/ /index.php$is_args$args;
+
+    location /socket.io/ {
+        proxy_pass http://websocket;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
     }


-    location ~ \.php$ {
-        try_files $uri /index.php =404;
-        fastcgi_pass php-upstream;
-        fastcgi_index index.php;
-        fastcgi_buffers 16 16k;
-        fastcgi_buffer_size 32k;
-        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-        #fixes timeouts
-        fastcgi_read_timeout 600;
-        include fastcgi_params;
+    location /socket.io/socket.io.js {
+        proxy_pass http://websocket;
     }

     location ~ /\.ht {

node-serverコンテナの8000番ポートでnode.jsを動かしているので、upstream websocketという名前で宣言してそれを使用。
https://ドメイン/socket.io/で来たリクエストを、node.jsのほうにプロキシして流す処理を宣言する。

docker-compose.ymlの編集

nginxの追加に合わせて修正する。

virtual-environment/provision/docker/docker-compose.yml
version: "3"

networks:
  backend:
    driver: ${NETWORKS_DRIVER}

volumes:
  mongo:
    driver: ${VOLUMES_DRIVER}

services:
  ### MongoDB ##############################################
  # // 省略
  node-server:
    build: ${QUORIDORN_PATH_ROOT}
    volumes:
      - ${QUORIDORN_PATH_ROOT}:/app
      - /app/node_modules
-     ports:
-       - "${QUORIDORN_SERVER_PORT}:8000"
    command: ["npm", "run", "node-server"]
    networks:
      - backend
    depends_on:
      - mongo


+  ### NGINX Server #########################################
+  nginx:
+    build:
+      context: ./nginx
+      args:
+        - CHANGE_SOURCE=${CHANGE_SOURCE}
+        - http_proxy
+        - https_proxy
+        - no_proxy
+    volumes:
+      - ${NGINX_HOST_LOG_PATH}:/var/log/nginx
+      - ${NGINX_SITES_PATH}:/etc/nginx/sites-available
+      - ${NGINX_SSL_PATH}:/etc/nginx/ssl
+    ports:
+      - "${NGINX_HOST_HTTPS_PORT}:443"
+    depends_on:
+      - node-server
+    networks:
+      - backend

もともと公開していた8000番ポートは、nginxによってwssでアクセスされる443からプロキシされるようになるため、不要になる。

環境変数の追加

virtual-environment/provision/docker/.env
### NGINX #################################################

NGINX_HOST_HTTP_PORT=80
NGINX_HOST_HTTPS_PORT=443
NGINX_HOST_LOG_PATH=./logs/nginx/
NGINX_SITES_PATH=./nginx/sites/
NGINX_SSL_PATH=./nginx/ssl/
### Environment ###########################################

# If you need to change the sources (i.e. to China), set CHANGE_SOURCE to true
CHANGE_SOURCE=false

クライアントサイドの設定

wsの8000ポートで接続していた部分をwssの443ポートに変える。
443ポートはデフォルトなので、省略できる。

/public/static/conf/connect.yaml
 # 向き先
 # quoridornServer: "wss://quori-dev.onlinesession.app"
 # quoridornServer: "http://localhost:2222"
-quoridornServer: "ws://192.168.60.79:8000"
+quoridornServer: "wss://192.168.60.79"

動作確認

vagrant upでのdockerの自動立ち上げがうまくいっていない。。。

仮想環境の起動

※ サーバ側とクライアント側両方で行う。

vagrant up
vagrant ssh
cd virtual-environment/provision/bash
./docker_restart.sh

起動したら、 https://192.168.74.60/quoridorn2/ にブラウザでアクセスする。

SSL証明書の問題

テスト用にオレオレ証明書を使っているため、クライアントから接続しようとすると
ERR_CERT_AUTHORITY_INVALIDのエラーがでて接続できない。

その場合、先に以下のサーバ側の URL をブラウザで開く。
https://192.168.60.79/socket.io/

詳細設定をクリック。

192.168.50.79 にアクセスする(安全ではありません)をクリック。
安全なのは自分が知ってる。

以下の画面が出れば成功。

クライアントの画面に戻って、ページの再読み込みを行う。

ERR_CERT_AUTHORITY_INVALIDのエラーが消えて、プレイルームが表示できた!

参考

laradock
Laradock の Nginx を SSL 化する
WSS が繋がらない
Nginx によるリバースプロキシの設定方法
websocket を使う際の意外な落とし穴
socketi.io
node.js 超入門 ①node.js で web サーバを作ってみる