結論
Docker Compose上でVue CLIのnpm run sreve
をすると、開発サーバーのホットリロードがうまく動作しない。
原因は、ブラウザからアクセスする開発サーバーのWebSocketのURLが正しくないことが原因。
プロジェクトルートにvue.config.js
をなければ作り、以下のように書くことで解決できる。
module.exports = {
devServer: {
client: {
host: '0.0.0.0',
webSocketURL: 'ws://0.0.0.0:8080/ws'
}
}
}
WebPackのバージョンが4なら、以下で動くと思われる(確認していないので不明)。
参考: https://stackoverflow.com/questions/71817054/dockerized-vue-app-hot-reload-does-not-work
module.exports = {
devServer: {
public: '0.0.0.0:8080'
}
}
説明: 実際にやってみる
環境
- macOS Big Sur 11.4
- @vue/cli 5.0.7
- Docker version 20.10.17
- docker-compose version 1.29.2
Dockerなしで動かす
Vue CLIでプロジェクトを作成する
vue create setsumei
開発サーバーを立ち上げる
cd setsumei
npm run serve
実行結果
⋊> npm run serve
> sestumei@0.1.0 serve
> vue-cli-service serve
INFO Starting development server...
DONE Compiled successfully in 2406ms
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.3.10:8080/
Note that the development build is not optimized.
To create a production build, run npm run build.
ブラウザで確認してみる
開発者ツールを開いて、ネットワークを見てみる
WebSocketが動いている!
HotReloadはWebSocketを使うことよって実現されている。
WebSocketの接続先のURLをみると、loclhost:8080
にアクセスしているのに、WebSocketは192.168.3.10:8080にアクセスしている。
これは、npm run serve
した時にコンソールに出るNetworkのURLとなっている。
Docker Composeで動かす
プロジェクトのルートにdocker-compose.yaml
を作成
version: "3.9"
services:
app:
image: node:16-alpine
command: npm run serve
ports:
- 8080:8080
working_dir: /app
volumes:
- .:/app
立ち上げる
⋊> docker-compose up
Creating network "sestumei_default" with the default driver
Creating sestumei_app_1 ... done
Attaching to sestumei_app_1
app_1 |
app_1 | > sestumei@0.1.0 serve
app_1 | > vue-cli-service serve
app_1 |
app_1 | INFO Starting development server...
DONE Compiled successfully in 24505ms12:34:56 AM
app_1 |
app_1 | App running at:
app_1 | - Local: http://localhost:8080/
app_1 | - Network: http://172.19.0.2:8080/
app_1 |
app_1 | Note that the development build is not optimized.
app_1 | To create a production build, run npm run build.
app_1 |
Build finished at 12:34:56 by 0.000s
ブラウザで確認してみる
原因と解決策
原因は、URLがDockerのネットワークの中のURLになっているから、本来はlocalhost:8080
に接続して欲しい。
開発サーバーのWebSocketのURLを変えるには、vue.config.js
を編集する。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
+ devServer: {
+ client: {
+ host: '0.0.0.0',
+ webSocketURL: 'ws://0.0.0.0:8080/ws'
+ }
}
})
もう一度Docker Composeで動かす
⋊> docker-compose up
Creating network "sestumei_default" with the default driver
Creating sestumei_app_1 ... done
Attaching to sestumei_app_1
app_1 |
app_1 | > sestumei@0.1.0 serve
app_1 | > vue-cli-service serve
app_1 |
app_1 | INFO Starting development server...
DONE Compiled successfully in 19368ms12:34:56 AM
app_1 |
app_1 | App running at:
app_1 | - Local: http://localhost:8080/
app_1 | - Network: http://172.20.0.2:8080/
app_1 |
app_1 | Note that the development build is not optimized.
app_1 | To create a production build, run npm run build.
app_1 |
Build finished at 12:34:56 by 0.000s
ブラウザで確認してみる
参考
webpackのドキュメントのwebSocketURLのところに書いてある。
webSocketURL
string
object
This option allows specifying URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).