Docker + WSL 2 でディスク使用量を戻す方法
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 ファイル自体を小さくする必要があります。
具体的には、下記の2つを行います。
- .vhdx ファイルの中の空き容量を増やす
- .vhdx ファイルを最適化して小さくする
.vhdx ファイルの中の空き容量を増やす
.vhdx ファイル自体のサイズを減らすためには、.vhdx ファイルの中に空き容量が無ければなりません。 空き容量があるから .vhdx ファイルを小さくできるのであって、空き容量が無いなら小さくできませんからね。
つまり、Docker で使用しなくなったコンテナやイメージなどを削除することは無駄な作業ではないということです。 ただ、それだけでは足りないというだけで、必要な作業ではあるということです。
Docker のディスクの使用量を確認する
Docker のディスク使用量を確認するには、docker system df
コマンドを使用します。
docker system df
Docker の未使用のデータを全て削除する
未使用のコンテナやイメージがたくさんある場合は、docker system prune
コマンドが便利です。
オプション無しで使用した場合は、未使用で「浮いている」(dangling)のコンテナ、イメージ、ネットワークが全て削除されます。 「浮いている」(dangling)とは、タグを持たず、どのコンテナからも参照されていないデータです。
未使用のコンテナ、イメージ、ネットワークを全て削除するには、--all
オプションを使用します。
--all
オプション には、エイリアス(別名) -a
オプションがあります。
なお、ボリュームはデフォルトでは削除されません。
そのボリュームを参照するコンテナがなかったために、重要なデータが削除されてしまうことを防止するためです。
ボリュームも削除するためには、--volumes
オプションを使用する必要があります。
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" ファイルがあります。
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
("%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx" の場合)
Optimize-VHD -Path "$Env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx" -Mode Full
("%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx" の場合)
Optimize-VHD -Path "$Env:LOCALAPPDATA\Packages\CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx" -Mode Full
参考サイト
- WSL2 Docker が PC のディスクを圧迫する - Qiita
- How to manage WSL disk space | Microsoft Learn
- docker system df | Docker ドキュメント
- 未使用 Docker オブジェクトの取り除き | Docker ドキュメント
- docker system prune | Docker ドキュメント
- windows - What does \\?\ mean when prepended to a file path - Stack Overflow
- How to reduce size of docker data volume in Docker Desktop for Windows v2 - DEV Community
- Optimize-VHD (Hyper-V) | Microsoft Learn
- ext4 - Wikipedia
- VHD (ファイルフォーマット) - Wikipedia