Docker + WSL 2 でディスク使用量を戻す方法

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

Docker はコンテナを作成するために大量のディスク容量を使用します。 コンテナを気軽に作ったり破棄したりしていると、いつのまにかディスク使用量がいっぱいになって困ることがあります。 ディスク使用量がいっぱいになったのなら、 使用しなくなったコンテナやイメージなどを削除すれば良いじゃないかと思うかもしれませんが、 Docker で WSL 2 を使用している場合、通常の方法ではディスク使用量は戻りません。 どうにかしましょう。

Docker で WSL 2 を使用しているとディスク使用量が戻らない

これは Docker というよりは WSL 2 に起因した現象です。 Docker のバックエンドに WSL 2 を使用している場合に発生します。 WSL 2 が起因なので、WSL 2 で Ubuntu や Debian などのディストリビューションを使用している場合でも同様に発生します。 Docker を使用していると大量のディスク容量を使用するので、この現象に気付きやすいというだけです。

ディスク使用量が戻らない原因

WSL 2 では、.vhdx ファイルという仮想のハードディスクファイルを使用してデータを保存しています。 物理的なディスクであればディスクの総容量は決まっていますが、 この .vhdx ファイルのサイズは動的に変化します。 足りなくなれば自動的に増えるようになっています。 しかしそれは良いのです。 効率的に容量を使用しているということですから。 問題なのは、自動で増えるのに、自動では減らないということです。

普通に考えてみるとわかるのですが、 ディスク内のファイルを削除したとしても、それは OS から見たディスクの使用量が減っているだけで、 ディスクとしての総容量は減ったりしません。 削除されたファイルの内容はごみデータとして、そのままディスク上には残り続けています。 ディスク自体は小さくなったりしないのです。

これは、仮想ハードディスクである .vhdx ファイルでも同じです。 .vhdx ファイルの中のファイルを削除しても、 .vhdx ファイルの中の空き容量が増えるだけで、 .vhdx ファイル自体は小さくなったりしないのです。

これが Docker のコンテナやイメージなどを削除しても、ディスクの使用量が戻らない原因です。 Docker のコンテナやイメージなどは .vhdx ファイル内のファイルとして保存されているので、 どれだけそれらを削除したとしても .vhdx ファイル自体のサイズは変わらないため、 ディスクの使用量が戻らないのです。

vhdx.png

解決策

ディスクの使用量を戻すためには、.vhdx ファイル自体を小さくする必要があります。

具体的には、下記の2つを行います。

  1. .vhdx ファイルの中の空き容量を増やす
  2. .vhdx ファイルを最適化して小さくする
vhdx2.png

.vhdx ファイルの中の空き容量を増やす

.vhdx ファイル自体のサイズを減らすためには、.vhdx ファイルの中に空き容量が無ければなりません。 空き容量があるから .vhdx ファイルを小さくできるのであって、空き容量が無いなら小さくできませんからね。

つまり、Docker で使用しなくなったコンテナやイメージなどを削除することは無駄な作業ではないということです。 ただ、それだけでは足りないというだけで、必要な作業ではあるということです。

Docker のディスクの使用量を確認する

Docker のディスク使用量を確認するには、docker system df コマンドを使用します。

docker system df

Docker の未使用のデータを全て削除する

未使用のコンテナやイメージがたくさんある場合は、docker system prune コマンドが便利です。

オプション無しで使用した場合は、未使用で「浮いている」(dangling)のコンテナ、イメージ、ネットワークが全て削除されます。 「浮いている」(dangling)とは、タグを持たず、どのコンテナからも参照されていないデータです。

未使用のコンテナ、イメージ、ネットワークを全て削除するには、--all オプションを使用します。 --all オプション には、エイリアス(別名) -a オプションがあります。

なお、ボリュームはデフォルトでは削除されません。 そのボリュームを参照するコンテナがなかったために、重要なデータが削除されてしまうことを防止するためです。 ボリュームも削除するためには、--volumes オプションを使用する必要があります。

例:「浮いている」(dangling)のコンテナ、イメージ、ネットワークを全て削除する場合
docker system prune
例:未使用のコンテナ、イメージ、ネットワークを全て削除する場合
docker system prune -a

.vhdx ファイルを最適化して小さくする

.vhdx ファイルの中の空き容量を増やせたら、次は .vhdx ファイルを最適化しましょう。 .vhdx ファイルを最適化すると、.vhdx ファイル自体のサイズが小さくなって、ディスク使用量が戻ります。

.vhdx ファイルを探す

まずは、最適化したい .vhdx ファイルがどこにあるのか探す必要があります。 ファイルの名前は "ext4.vhdx" です。 "ext4" というのは、Linux のファイルシステムの名前です。 Windows でいうところの NTFS のようなものですね。

Docker の .vhdx ファイルを探す

Docker の .vhdx ファイルの場所は固定なので簡単に見つかります。 Docker は、WSL 2 で "docker-desktop" と "docker-desktop-data" の2つのディストリビューションを使用していますが、 コンテナやイメージなどのデータは "docker-desktop-data" の方で管理されています。 ディスク使用量が全然違うのですぐにわかると思います。

ディストリビューション .vhdx の場所
docker-desktop %LOCALAPPDATA%\Docker\wsl\distro
docker-desktop-data %LOCALAPPDATA%\Docker\wsl\data

WSL 2 の全てのディストリビューションの .vhdx ファイルを探す

この現象は WSL 2 が起因なので、WSL 2 で Ubuntu や Debian などの他のディストリビューションを使用している場合でも同様に発生します。 WSL 2 の全てのディストリビューションの .vhdx ファイルの場所を調べたい場合は、 PowerShell で下記のコマンドを実行します。 やっている内容としては、WSL 2 が管理しているディストリビューションの情報をレジストリから取得して表示しています。 表示された BasePath のディレクトリに "ext4.vhdx" ファイルがあります。

PowerShell
Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss
出力内容
    Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss


Name                           Property
----                           --------
{683a8770-eb3d-4890-ad37-81ec2 State             : 1
90cfe80}                       DistributionName  : Ubuntu
                               Version           : 2
                               BasePath          : C:\Users\Test\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState
                               Flags             : 15
                               DefaultUid        : 1000
                               PackageFamilyName : CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc
{e26df7e4-3eba-41dd-9990-9d7ca State            : 1
3049cc7}                       DistributionName : docker-desktop-data
                               Version          : 2
                               BasePath         : \\?\C:\Users\Test\AppData\Local\Docker\wsl\data
                               Flags            : 15
                               DefaultUid       : 0
{e28f06e8-0ce5-4ff4-b5ef-11ad7 State            : 1
8f5b79b}                       DistributionName : docker-desktop
                               Version          : 2
                               BasePath         : \\?\C:\Users\Test\AppData\Local\Docker\wsl\distro
                               Flags            : 15
                               DefaultUid       : 0

ちなみにですが、パスが \\?\ で始まっているものは、Windows で長いパスを使用したい時に使用するものらしいです。 通常だと255文字の制限がかかるところ、\\?\ で始めると32,767文字まで使えるようになるとのこと。 まぁ、特に気にせず普通のパスと同じように考えれば良いでしょう。

WSL 2 のディストリビューションを停止させる

次に、最適化したい .vhdx を使用している WSL 2 のディストリビューションが停止していることを確認しましょう。 .vhdx ファイルが使用中だと最適化できません。 下記のコマンドを実行して、ディストリビューションの状態が Stopped になっていることを確認してください。 Running ならディストリビューションを停止させてください。

Docker は、WSL 2 で "docker-desktop" と "docker-desktop-data" の2つのディストリビューションを使用しているので、 念のため両方とも Stopped になっていることを確認しましょう。 Docker Desktop を終了させてしばらく待てば Stopped になると思います。

wsl -l -v
出力内容
  NAME                   STATE           VERSION
* Ubuntu                 Stopped         2
  docker-desktop         Stopped         2
  docker-desktop-data    Stopped         2

全てのディストリビューションを停止させる

全てのディストリビューションをすぐに停止させたい場合は、wsl コマンドで、--shutdown オプションを使用します。 このコマンドを実行すると、実行中のすべてのディストリビューションがシャットダウンされるので、慎重に使用してください。

wsl --shutdown

.vhdx ファイルを最適化する

あとは .vhdx ファイルを最適化するだけです。 管理者権限PowerShell で、下記のコマンドを実行します。 Optimize-VHD コマンドを実行すると、.vhdx ファイルを最適化することができます。 .vhdx ファイル自体のサイズが小さくなって、ディスク使用量が戻ります。

書式
Optimize-VHD -Path <.vhdxファイルのパス> -Mode Full
例:Docker の "docker-desktop-data" を最適化する場合
"%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx" の場合)
PowerShell
Optimize-VHD -Path "$Env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx" -Mode Full
例:WSL 2 の "Ubuntu" を最適化する場合
"%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx" の場合)
PowerShell
Optimize-VHD -Path "$Env:LOCALAPPDATA\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx" -Mode Full

参考サイト

関連記事

Docker で開発環境を作るのって結構大変です。構成を気軽に組み替えたりできるため自由度が高いですが、その分必要になる知識も多いですし、必要な作業も多いです。まずは、XAMPP でおなじみの Apache と PHP を組み合わせた Web サーバーを作るところから始めてみましょう。Docker で Apache + ...
Docker は、構成を気軽に組み替えたりできるので、とても便利ですよね。Windows で Docker を使って開発している方も多いと思うのですが、個人的にはどうしても気が乗らない理由がありました。それは処理速度です。遅い。遅すぎる。めちゃくちゃ遅い。つらい。耐えられない。。。ということで調査しました。いろいろと調 ...
最近では、アプリケーションの実行環境の構築に Docker を使うことも珍しくなくなりました。Docker は便利ではあるのかもしれませんが、難しく感じて敬遠されている人もいるのではないでしょうか。その感覚はおそらく間違っていません。実際、知れば知るほど奥が深い技術だと感じてしまいます。もはや沼というか深淵を覗いている ...

お知らせ

記事検索

最新記事

人気記事

RSSフィード

フィードバック

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

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

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

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