Windows の Docker 環境を高速化する方法

この記事は最終更新日から 1年以上 が経過しています。

Docker は、構成を気軽に組み替えたりできるので、とても便利ですよね。 Windows で Docker を使って開発している方も多いと思うのですが、個人的にはどうしても気が乗らない理由がありました。 それは処理速度です。遅い。遅すぎる。めちゃくちゃ遅い。つらい。耐えられない。。。ということで調査しました。 いろいろと調べていくうちに、Windows で Docker 環境の速度を上げ、かつ作業効率を落とさない方法を発見したので、備忘録としてメモしておきます。 もう知ってる人もいると思いますが、誰かの役に立てば幸いです。

遅い原因

Windows の Docker が遅くなるのは、ほぼほぼバインドマウントが原因のもよう。 バインドマウントというのは、ホストにあるファイルを、Docker のコンテナから参照することができるようになる機能です。

バインドマウントがわからないという方は、まずは「Docker の使い方(その4:ボリューム)」を参考にしてください。

バインドマウントを使用すると、 アプリケーションのソースコード(スクリプト言語の場合)をホストに置いておけるため、 好きな IDE やテキストエディタ(VS Code など)を使用して開発を行うことができます。 大変便利な機能なので、バインドマウントは使いたい。 しかし、バインドマウントを使うと遅くなってしまう。

bindmount.png
例: Windows の "./html" と、コンテナの "/var/www/html" をバインドマウントする場合
docker-compose.yml
version: "3.8"
services:
  httpd:
    build: ./httpd
    ports:
      - 8080:80
    volumes:
      - ./html:/var/www/html

解決策1:名前付きボリュームを使う

よくある解決方法としては、バインドマウントするファイルを減らすために、名前付きボリュームを使うという方法です。 例えば、アプリケーションで使用しているライブラリやフレームワーク(例えば、PHP の Composer を使っているなら vendor ディレクトリ配下)を名前付きボリュームに置きます。 こうすることで、バインドマウントで参照されるファイルが減るため、動作速度が上がります。

しかしこの方法は、ファイルがバラバラに配置されることになるため、 どのファイルがホストに置かれているのか、名前付きボリュームに置かれているのか混乱しますし、 名前付きボリュームに置いたファイルを変更するためにはコンテナに入って作業しなければならなくなります。 また、ホストに置かれているファイルは相変わらず遅いままです。

手軽にできる方法ではあるので、よく使われている方法なのかもしれません。

bindmount2.png
例: "/var/www/html/vendor" だけ名前付きボリュームに置く場合
docker-compose.yml
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 を使う

困ったときは公式サイトを見ればいいということで、下記に公式サイトの記述を引用します。

>> ファイルのバインド マウント時、ファイルシステムの性能を最大限に活用するには、ソースコードや他のデータの保管を、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)を使えば良いんです!

bindmount3.png

では、どうするか。具体的には下記を行います。

  1. WSL 2 で Linux 環境を作る
  2. Docker で WSL 2 と連携する設定にする
  3. バインドマウント先に 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.png

ディストリビューションがインストールできたら、後はその中にバインドマウントしたいファイルを置くだけです。 エクスプローラーで開けますので普通に置けば良いです。 場所はどこでも良いですが、ホームディレクトリの配下がわかりやすくて良いかと思います。 注意しないといけない点としては、"\\wsl.localhost" 配下は Linux ですので、Linux のユーザーとパーミッションが適用されるようになります。 ファイルが読み込めないとか書き込めないとかあれば、ユーザーとパーミッションを確認してください。

wsl2.png

Docker で WSL 2 と連携する設定にする

WSL 2 で Linux 環境が作れたら、次は Docker で WSL 2 と連携する設定です。 まずは、設定の「General」の「Use the WSL 2 based engine」を有効にします。

docker_general.png

次に、設定の「Resouces」の「WSL Integration」で、使用したい WSL 2 のディストリビューションを有効にします。 WSL 2 を使用するためには、使用している WSL 2 のディストリビューションが起動している必要があるのですが、 ここで有効にすると、Docker がそのディストリビューションを自動的に起動してくれるようになります。

WSL 2 で既定に設定してあるディストリビューションを起動するか、既定に設定していないならどのディストリビューションを起動するのかという設定になります。 この記事では、説明のために Ubuntu を使っていますので、Ubuntu を有効にします。

docker_resources.png

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 を指定して、コンテナをビルドして起動するだけです。

例: WSL 2 の "\\wsl.localhost\Ubuntu\home\test\www\html" と、
コンテナの "/var/www/html" をバインドマウントする場合
docker-compose.yml
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\" と入力して適用します。

tortoisegit.png

参考サイト

関連記事

Windows 上の Docker を高速化するためには、名前付きボリュームを使うか、WSL 2 を使うと良いというのは、以前の記事「Windows の Docker 環境を高速化する方法」で書きましたが、それら2つの方法に並ぶ、第3の方法を見つけたので、備忘録としてメモしておきます。結局バインドマウントが原因以前の記 ...
前回、「Docker の使い方(その3:コンテナイメージ)」の続きです。今回はボリュームについてです。ボリュームコンテナは作り直すと中身が初期状態に戻ってしまいます。ですが、コンテナの中のアプリケーションが作成したファイルなど、残しておいてほしいファイルもあると思います。例えばデータベースに保存されているデータなどです ...
Windows 上の Docker を高速化するためには WSL 2 を使うと良いというのは、以前の記事「Windows の Docker 環境を高速化する方法」で書きました。WSL 2 にファイルを置くと Docker が早くなるのは良いのですが、それに起因して別の問題が発生します。その WSL 2 に置いたファイル ...
Windows 上の Docker を高速化するためには WSL 2 を使うと良いというのは、以前の記事「Windows の Docker 環境を高速化する方法」で書きました。そこで、今回はその WSL 2 上に PHP と JavaScript の開発環境を作る方法を、備忘録としてメモしておきます。WSL 2 の使い ...
Windows で開発している際、動作確認のために Linux のプログラムやコマンドを動かしたいなと思うことがあります。そんな場合に便利なのが WSL(Windows Subsystem for Linux)です。WSL(Windows Subsystem for Linux)とは?WSL(Windows Subsy ...

記事検索

最新記事

人気記事

RSSフィード

お知らせ

フィードバック

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

匿名でフィードバックする
匿名でフィードバックする

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

なお、このフォームから入力された内容について、管理者から返信はできませんので注意してください。 もし、管理者からの返信が必要であれば、X(Twitter) もしくは、お問い合わせより、お願いします。

  • フィードバックの送信が完了しました。