Windows の Docker 環境を高速化する方法
Docker は、構成を気軽に組み替えたりできるので、とても便利ですよね。 Windows で Docker を使って開発している方も多いと思うのですが、個人的にはどうしても気が乗らない理由がありました。 それは処理速度です。遅い。遅すぎる。めちゃくちゃ遅い。つらい。耐えられない。。。ということで調査しました。 いろいろと調べていくうちに、Windows で Docker 環境の速度を上げ、かつ作業効率を落とさない方法を発見したので、備忘録としてメモしておきます。 もう知ってる人もいると思いますが、誰かの役に立てば幸いです。
遅い原因
Windows の Docker が遅くなるのは、ほぼほぼバインドマウントが原因のもよう。 バインドマウントというのは、ホストにあるファイルを、Docker のコンテナから参照することができるようになる機能です。
バインドマウントがわからないという方は、まずは「Docker の使い方(その4:ボリューム)」を参考にしてください。
バインドマウントを使用すると、 アプリケーションのソースコード(スクリプト言語の場合)をホストに置いておけるため、 好きな IDE やテキストエディタ(VS Code など)を使用して開発を行うことができます。 大変便利な機能なので、バインドマウントは使いたい。 しかし、バインドマウントを使うと遅くなってしまう。
version: "3.8"
services:
httpd:
build: ./httpd
ports:
- 8080:80
volumes:
- ./html:/var/www/html
解決策1:名前付きボリュームを使う
よくある解決方法としては、バインドマウントするファイルを減らすために、名前付きボリュームを使うという方法です。 例えば、アプリケーションで使用しているライブラリやフレームワーク(例えば、PHP の Composer を使っているなら vendor ディレクトリ配下)を名前付きボリュームに置きます。 こうすることで、バインドマウントで参照されるファイルが減るため、動作速度が上がります。
しかしこの方法は、ファイルがバラバラに配置されることになるため、 どのファイルがホストに置かれているのか、名前付きボリュームに置かれているのか混乱しますし、 名前付きボリュームに置いたファイルを変更するためにはコンテナに入って作業しなければならなくなります。 また、ホストに置かれているファイルは相変わらず遅いままです。
手軽にできる方法ではあるので、よく使われている方法なのかもしれません。
version: "3.8" services: httpd: build: ./httpd ports: - 8080:80 volumes: - ./html:/var/www/html - app-vendor:/var/www/html/vendor volumes: app-vendor:
解決策2:WSL 2 を使う
困ったときは公式サイトを見ればいいということで、下記に公式サイトの記述を引用します。
- Docker Desktop WSL 2 バックエンド — Docker-docs-ja 20.10 ドキュメント
- Docker Desktop WSL 2 backend on Windows | Docker Documentation
>> ファイルのバインド マウント時、ファイルシステムの性能を最大限に活用するには、ソースコードや他のデータの保管を、Windows ファイルシステム上ではなく、Linux コンテナ内(例: docker run -v <host-path>:<container-path> を指定)のファイルシステム内にバインド マウントするのを推奨します。
>> リモートの Windows ホスト上よりも、Linux ファイルシステムにファイルをバインド マウントする方が、性能がより高くなります。
>> 従って、 docker run -v /mnt/c/users:/users を避けるべきです( /mnt/c は Windows によってマウントされる場所です)。
ですって!……これ、意味わかりますか?
つまりですね、バインドマウントが遅いのは、ホストが Windows であり、Docker のコンテナが Linux であるため、 Windows のファイルシステム(例えば、NTFS)から、Linux のファイルシステムに変換したりしないといけないから遅いのだということです。 逆に言えば、Linux 同士でバインドマウントするなら早いということです。 なので、バインドマウントするなら、Windows ではなく Linux にファイルを置けということみたいです。
Windows なのに、Linux にファイルを置く? そんなのいったいどうやってやるんだと思いますよね。 でも Windows はできるんです。 そうです! WSL 2(Windows Subsystem for Linux 2)を使えば良いんです!
では、どうするか。具体的には下記を行います。
- WSL 2 で Linux 環境を作る
- Docker で WSL 2 と連携する設定にする
- バインドマウント先に WSL 2 の Linux 環境を指定する
WSL 2 で Linux 環境を作る
WSL 2 の使い方がわからないという方は、まずは「WSL(Windows Subsystem for Linux)の使い方」を参考にしてください。 好きなディストリビューションをインストールして使用できるようにしてください。 Ubuntu でも Debian でも Linux なら何でも良いです。 この記事では、説明のために Ubuntu を使います。
Windows から WSL 2 の各ディストリビューションには、"\\wsl$" もしくは、"\\wsl.localhost" でアクセスできます。 以前は、"\\wsl$" を使用していましたが、新しく "\\wsl.localhost" が使えるようになったようです。 また、"\\wsl.localhost" の方がデフォルトになっているらしいです。
ディストリビューションがインストールできたら、後はその中にバインドマウントしたいファイルを置くだけです。 エクスプローラーで開けますので普通に置けば良いです。 場所はどこでも良いですが、ホームディレクトリの配下がわかりやすくて良いかと思います。 注意しないといけない点としては、"\\wsl.localhost" 配下は Linux ですので、Linux のユーザーとパーミッションが適用されるようになります。 ファイルが読み込めないとか書き込めないとかあれば、ユーザーとパーミッションを確認してください。
Docker で WSL 2 と連携する設定にする
WSL 2 で Linux 環境が作れたら、次は Docker で WSL 2 と連携する設定です。 まずは、設定の「General」の「Use the WSL 2 based engine」を有効にします。
次に、設定の「Resouces」の「WSL Integration」で、使用したい WSL 2 のディストリビューションを有効にします。 WSL 2 を使用するためには、使用している WSL 2 のディストリビューションが起動している必要があるのですが、 ここで有効にすると、Docker がそのディストリビューションを自動的に起動してくれるようになります。
WSL 2 で既定に設定してあるディストリビューションを起動するか、既定に設定していないならどのディストリビューションを起動するのかという設定になります。 この記事では、説明のために Ubuntu を使っていますので、Ubuntu を有効にします。
WSL 2 の各ディストリビューションの稼働状況が知りたい場合は、wsl
コマンドに -l
オプションと -v
オプションを付けて使用します。
"Running" と表示されたなら、そのディストリビューションは起動しています。
wsl -l -v
NAME STATE VERSION * Ubuntu Running 2 Debian Stopped 2 docker-desktop Running 2 docker-desktop-data Running 2
バインドマウント先に WSL 2 の Linux 環境を指定する
ここまでで WSL 2 を使用するための準備はできました。 後は、バインドマウント先に WSL 2 を指定して、コンテナをビルドして起動するだけです。
コンテナの "/var/www/html" をバインドマウントする場合
version: "3.8"
services:
httpd:
build: ./httpd
ports:
- 8080:80
volumes:
- \\wsl.localhost\Ubuntu\home\test\www\html:/var/www/html
docker compose build && docker compose up -d
おまけ:WSL 2 で TortoiseGit のオーバーレイアイコンを表示する
最後に、おまけで TortoiseGit 使ってる人に向けて、"\\wsl.localhost" 配下でオーバーレイアイコンを表示する方法です。 オーバーレイアイコンというのは、Git で管理されているファイルのアイコンに緑のチェックマークがつくあれです。 WSL 2 の "\\wsl.localhost" 配下では、そのオーバーレイアイコンが表示されません。 開発環境を WSL 2 に移行した場合は困ると思います。
表示されるように変更するには、「Settings > Icon Overlays」で "Drive Types" の "Network drives" にチェックを付けるか、 もしくは "Include paths" に "\\wsl.localhost\" と入力して適用します。
参考サイト
- WindowsでDockerを使う時、正しくファイル配置しないと激重になるので注意 - Qiita
- Docker Desktop WSL 2 バックエンド — Docker-docs-ja 20.10 ドキュメント
- Docker Desktop WSL 2 backend on Windows | Docker Documentation
- windows subsystem for linux - Convert \\wsl$\ path to URI-compliant \\wsl.localhost\ - Super User
- git - How do you get TortoiseGit GUI for Windows Explorer working in WSL2 Linux including Windows 10? - Stack Overflow