📝

Windows+Dockerでホットリロード全般が効かない場合の対策

2024/04/06に公開

はじめに

WindowsのDocker環境でRustのcargo wacth -x runやReactのホットリロード、Go言語のAirなど、ホットリロードが毎回毎回効かずに調べてもストレートに解決策を書いている記事がなく(見つけられなかっただけ。もしくは当たり前すぎて記事がない可能性も)毎回頭を抱えていたんですが、少し前にあっさり解決したので自己紹介より前に記事に落とします。

マウントもしてるし..コンテナのソースは変わってるのに効かない..ポーリングもダメ..
↑iあっさり解決します。

開発環境

Windows11
Docker for windows
rustup 1.27.0
actix-web 4.5.1
※言語は原因と関係ないです

解決策

認識が間違っている可能性も高いですが、
WSL2はWindowsのファイル変更イベントを検知できないのが理由でした。
なのでLinuxファイルシステムの中で開発すればOKです。

https://banatech.net/blog/view/54

上記の記事によるとファイル変更を検知するinotifyという機能がWindowsのファイルシステムとLinuxのファイルシステムでまたがっていると機能しないためHot reload機能も動作しないようです.

手順も含め解説します。

前提の解説

Docker for Windowsをインストールする際にWSL2をインストールしたと思いますが、これはWindows System For LinuxといってWindowsの仮想ディスクにLinuxファイルシステムを置いており、そのそのLinuxファイルシステムの中でDockerが稼働しています。

めちゃくちゃ浅く言うと、Windowsから別PCのLinuxを遠隔操作しているようなものなんです。

それを前提に置いたうえで、

  • アプリケーションはマウントしたプロジェクトを元にDockerのコンテナ内で起動している
  • Dockerのマウントとはホストマシンとファイル自体を同期するもの
  • ホットリロードはソースの変更ではなくファイルの変更イベントをトリガーに発火するもの

つまりファイルの同期はしているもののホストマシン側で何をしているのかをLinuxは全く知らないので、ホストマシン側でソースをいじっても、Linuxの中のDockerの中のアプリケーション君はソースが変わってる事すら認識しておらずホットリロードも動かないというわけです。

Linuxファイルシステムの中で開発する手順

手順1

まずはWSLのデフォルトバージョンがWSL2であるか確認します。
DockerはWSL2上で動いてるので問題ないと思いますが念のため。

PowerShell
wsl --set-default-version 2

手順2

Microsoft StoreでUbuntu20.04 LTSダウンロードします。

WindowsのPCなら必ず入ってると思うのでスタートメニューから検索してください。
ダウンロードが完了すると、ダウンロードボタンが開くボタンへ切り替わるのでUbuntu開きます。

Ubuntuを開くと初期化処理が始まるので少し待つと、ユーザー名とパスワードを設定するよう求められるので、任意のものを設定してください。

設定が終わるとコマンドが叩けるようになるので、とりあえず今後プロジェクトを配置していく親ディレクトリを作成します。

ubuntu
user@localhost:~$ mkdir workspase
user@localhost:~$ ls
workspace

Windowsのエクスプローラーを開き、Linuxの中にUbuntu20.04ディレクトリがあるのを確認します。Ubuntu-20.04\home\ユーザー名\workspace
ここの/ユーザー名/以降はCドライブの/ユーザー名/以降のように自由に使ってOKです。

ここまででWSL2でファイルシステムを使う準備が整いました。

手順3

Docker for windowsでUbuntu20.04からDockerデーモンへの接続を許可します。

まずはDocker for windowsを開き、
設定 > Resouces > WSL integration > Ubuntu20.04をチェック > Apply restart
の順に操作してください。

その後、Ubuntuでコマンドを叩きます。

Ubuntu20.04
sudo usermod -aG docker $USER

設定を反映させるため、Dockerのシャットダウン、WSLのシャットダウンなどが必要なのですが面倒なので一度PCを再起動し、起動後にUbuntuでコマンドを叩き、Dockerのバージョンが出ればUbuntuからDockerが使用可能になります。

Ubuntu20.04
user@localhost:~$ docker -v
Docker version 25.0.3, build 4debf41

ここまで来れば、先ほど作成したworkspaseディレクトリにプロジェクトを移してdocker compose upすればOKです。
Linuxファイルシステムで開発することで同じPCで作業しているのと同じ状態なので、ファイルシステムの変更も検知し、ホットリロードがちゃんと効きます。

以上で最低限のセットアップは完了です!

おわり

ここで紹介したのは最低限のセットアップなので、まだまだやることはありますが、これ以降は記事が多くありますので割愛します。

ちなみにvisual studio codeのプラグイン「WSL」プラグインをインストールすることで、幸せになれます。

また、めちゃくちゃ今更ですが、これからWSL上で開発するということは新PCを買ったのと同じで今までホストマシンでグローバルにインストールしていたCLIや各言語もセットアップすることになります。
セットアップと言っても各種コマンドでインストールするくらいです。

ホットリロードがなしでずっと開発するよりマシです。マシだよね..?

以上、誰かの参考になれば幸いです。

参考

WSL+DockerでHot reload が動作しない
Dockerを使っていてhot reload系が効かなかったとき
Docker環境でReactのホットリロードが効かない

Discussion