📑

Docker+Nuxt3+SSL+Nginx-Proxy環境でHMRを使える様にする

2023/05/17に公開

株式会社ウェイブで新規サービスの開発を行なっております、こしけです!
タイトルにもある通り、Docker+Nuxt3+SSL+Nginx-Proxy環境でHMRを使える様にするまで何点かはまったポイントがありましたので、同じ様な事象で悩んでいる人の助けになればと思いこの記事を書きました!
基本的にはこちらのissueの内容を参考に今回の対応を行っております!

ハマったポイント①

SSL対応後にページにアクセスしてみた所、下記の様なエラーが表示されました。

client.ts:78 Mixed Content: The page at 'https://hogehoge.jp' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://hogehoge.jp:24678/_nuxt/'. This request has been blocked; this endpoint must be available over WSS.

原因

WebSocketsを利用している箇所で、httpsの場合はwss(WebSockets over SSL)を利用しなくてはいけないが、wsを利用してしまっているからでした。
wsとwssの違いについては下記のサイトが分かりやすかったです。
WebSocket

対策

nuxt.configのhmrの設定でprotocolをwssに指定してあげればこのエラーは発生しなくなりました。

nuxt.config
vite: {
    server: {
      hmr: {
        clientPort: 443,
        protocol: "wss", ←これを追加する
      },
    },
  }

ハマったポイント②

①の対応後に再度アクセスしてみたところ何度もページがリロードされてしまう現象が発生しました。
コンソールには下記の様なエラーが表示されていました。

WebSocket connection to 'wss://hogehoge.jp/_nuxt/' failed:

原因

nginx-proxyの設定で'https://hogehoge.jp'にアクセスが来た場合に全てlocalhostの3000番portに飛ばしているからでした。
viteのhmrでは24678番port(デフォルト)にリクエストを飛ばしており、そこでの疎通が失敗した場合はリロードが発生する様です。

compose.yaml
~~~
    environment:
      VIRTUAL_HOST: ${DEV_FQDN_NAME:-hogehoge.jp}
      VIRTUAL_PORT: 3000
~~~

対策

viteのhmrリクエストの場合はlocalhostの24678番portに飛ばす様にすればこちらの問題は解決しました。
具体的な対応内容は以下の通りです。
① nuxt.configの設定に下記を追加

nuxt.config
vite: {
    server: {
      hmr: {
        clientPort: 443,
        protocol: "wss",
	path: 'hmr/', ←これを追加する
      },
    },
  }

この対応を行うことでhmrのリクエストの際のpathを変更することが出来ます。
今回の例ですとwss://hogehoge.jp/_nuxt/hmr/にリクエストが飛ぶ様になります。

② nginx-proxy側の設定変更
nginx-proxy側で/_nuxt/hmr/にアクセスが来た場合は24678番portに飛ばす設定を行います。
nginxであればdefault.confなどでlocationを設定すれば良いのですが、nginx-proxyを使っている場合はlocationのオーバーライドを行う必要があります。
ここのやり方が分からずだいぶハマったのですが、公式ドキュメントにしっかり記載されていました、、、😇
Overriding location blocks
今回の場合は下記のファイルを作成して/nginx/vhost.dディレクトリに配置し、このディレクトリをコンテナ側の/etc/nginx/vhost.dにマウントする様にしました。

# 元々記載されていたもの
location / {
  proxy_pass http://hogehoge.jp;
  set $upstream_keepalive false;
}

# /_nuxt/hmr/にアクセスが来た場合の設定
location /_nuxt/hmr/ {
  proxy_pass http://front:24678;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;
}

元々記載されていたものを消してしまうと、hmr以外のリクエストが失敗してしまうので注意してください。
compose.yamlの方は下記を追加しました。

compose.yaml
    volumes:
      ~~~
      - ./nginx/vhost.d:/etc/nginx/vhost.d:ro

今回の対応を行ってみて

だいぶ苦戦はしてしまいましたが、普段何気なく使っているnginx-proxyの仕組みやnuxtのhmrがどの様な経路を辿っているかなど勉強になることが数多くありました!
今後も何かにハマった際はとりあえず動くからokではなく、どの様な仕組みでそれが動いているのかなどしっかり深掘りしながら学んでいければと思います!

最後に

株式会社ウェイブでは、電子コミックやアニメ配信サービスなどを自社開発で運営しております。
nuxt3などの新しい技術を積極的に取り入れているモダンな環境が整っているウェイブで一緒に働いてみませんか?
興味ある方は是非こちらをご覧ください!
https://recruit.wwwave.jp/career/

wwwave's Techblog

Discussion