WSL2 と Docker がディスクを圧迫する理由と ext4.vhdx の縮小方法
仮想ディスクは大きくなるだけで、自動的には縮まない
短い答え: WSL2 は Linux のファイルシステム全体を `ext4.vhdx` という仮想ディスクに保存します。このファイルは必要に応じて大きくなりますが、中のファイルを削除しても小さくはなりません。空き容量を取り戻すには、まずディストリビューション内部を整理し、`wsl --shutdown` を実行してから `diskpart` で圧縮します。
開発マシンで「C ドライブがいっぱいなのに原因が見つからない」という状況の最も多い原因がこれです。ディスク解析ツールは 80 GB の単一ファイルを示しますが、削除すると Linux 環境ごと消えるため手が出せません。この記事では、そのファイルの正体、安全に縮小する方法、そして再び膨らませないための設定を説明します。
要点
- WSL2 は Linux ファイルシステム全体を 1 つの `ext4.vhdx` 仮想ディスクに保存し、このファイルは拡大するだけで自動的には縮小しません。
- ファイルは通常 `%LOCALAPPDATA%\Packages\<ディストリビューション>\LocalState\ext4.vhdx` にあり、Docker Desktop は独自の `docker_data.vhdx` を使います。
- 順序が重要です。まずディストリビューション「内部」のデータを削除し、その後で仮想ディスクを圧縮します。
- Docker では `docker system prune -a --volumes` だけで数十ギガバイトが空くことがよくあります。
- 圧縮の前に `wsl --shutdown` が必須です。使用中のファイルは縮小できません。
- WSL 2.0 以降では `.wslconfig` に `sparseVhd=true` を追加すると、ディスクが自動的に縮むようになります。
なぜ大きくなる一方で縮まないのか
WSL2 は本物の仮想マシンであり、Linux のファイルシステム全体を Windows 側の 1 つのファイル `ext4.vhdx` に格納します。これは動的に拡張する仮想ディスクです。内部に 5 GB のデータがあればファイルは約 5 GB を占め、60 GB 書き込めば 60 GB まで成長します。
問題は逆方向で起こります。内部で 50 GB の Docker イメージを削除すると Linux 側では空き容量として報告されますが、Windows 側の VHDX ファイルのサイズはまったく変わりません。仮想ディスク形式は解放されたブロックを「未使用」と印を付けるだけで、ファイルを物理的に短くしないからです。結果として `df -h` は内部に十分な空きを示す一方、Windows は C ドライブが満杯だと表示します。
WSL2 バックエンドの Docker Desktop はこの影響を倍にします。Docker は独自のディストリビューションをインストールし、イメージ、レイヤー、ボリュームを別の `docker_data.vhdx` に保存します。数年使った開発マシンでは、この 2 つのファイルの合計が 100 GB を軽く超えます。
まず内部: 圧縮の前に何を削除するか
圧縮は魔法ではなく、内部で実際に空いているブロックだけを返します。したがって最初の手順は常にディストリビューションの掃除です。Debian や Ubuntu 系では `sudo apt clean` がダウンロード済みパッケージのキャッシュを削除し、`sudo apt autoremove --purge` がどのパッケージからも不要になった依存関係を取り除きます。
Docker を使っているなら、本当の効果はそこにあります。`docker system df` はイメージ、コンテナ、ボリューム、ビルドキャッシュがそれぞれどれだけ占めているかを分けて表示します。`docker system prune -a --volumes` は使用中でないものをすべて削除します。未使用ボリュームも消えるため、残したいデータベースは先にエクスポートしてください。
ビルドキャッシュは最大の項目でありながら見落とされがちです。`docker builder prune -a` はキャッシュだけを対象とし、イメージには触れません。Node.js のプロジェクトでは、WSL 内の `node_modules` フォルダーに加えて `~/.npm` や `~/.cache` がさらに数十ギガバイトを占めることがあります。
圧縮: 領域を Windows に返す
内部を整理したら、仮想ディスクを物理的に短くします。前提として WSL が完全に停止していることが必要です。PowerShell で `wsl --shutdown` を実行し、Docker Desktop が開いていれば閉じます。プロセスがファイルを保持したままだと、アクセス拒否エラーで圧縮は失敗します。
管理者権限の PowerShell で `diskpart` を起動し、次の手順を順に実行します。`select vdisk file="C:\Users\名前\AppData\Local\Packages\...\ext4.vhdx"`、続いて `attach vdisk readonly`、`compact vdisk`、最後に `detach vdisk` です。読み取り専用でのアタッチが重要で、書き込み可能でマウントすると圧縮は実行されません。
Hyper-V コンポーネントが導入済みのシステムには 1 行の代替手段もあります。`Optimize-VHD -Path "パス\ext4.vhdx" -Mode Full` です。ただしこのコマンドレットは Windows Home エディションには存在しないため、既定としては `diskpart` の方が安全です。完了後、ファイルサイズは内部の実使用量に近づきます。
再発を防ぐには
WSL 2.0 で Microsoft はスパース仮想ディスクのサポートを追加しました。`%USERPROFILE%\.wslconfig` の `[experimental]` セクションに `sparseVhd=true` を追加して `wsl --shutdown` を実行すると、それ以降に作成されたディスクは内部で領域が空くたびに自動的に縮み始めます。既存のディストリビューションを変換するには `wsl --manage <ディストリビューション> --set-sparse true` を使います。
習慣としては 2 点が有効です。1 つは Docker のビルドキャッシュを定期的に削除すること。ほとんどのマシンでは月に一度 `docker builder prune -a` を実行すれば十分です。もう 1 つは大きなデータセットを Windows 側に置き、`/mnt/c` 経由でアクセスすること。WSL のファイルシステムに保存しなければ、そのデータが仮想ディスクを膨らませることはありません。
そもそもこれらのファイルに気づくこと自体が難題です。単一のファイルとして現れるため、フォルダーサイズで判断するツールでは目立ちません。Disk Mop の「大きいファイル」モジュールはドライブ上の最大サイズのファイルを順に並べ、`ext4.vhdx` はたいてい上位 3 件に入ります。Disk Treemap 表示では、同じファイルが画面の大部分を占める 1 つの長方形として現れます。
よくある質問
ext4.vhdx をそのまま削除してもよいですか。
いいえ。このファイルは WSL ディストリビューションそのものであり、インストール済みパッケージ、プロジェクト、データベースがすべて内部にあります。削除するとディストリビューションが完全に失われます。正しい手順は、中身を整理してからディスクを圧縮することです。
圧縮でデータが危険にさらされますか。
いいえ。`compact vdisk` は仮想ディスクファイルの未使用ブロックを破棄するだけで、ファイルシステム内のデータには触れません。それでも事前に `wsl --shutdown` で WSL を正しく停止し、重要なプロジェクトのバックアップを持っておくのは良い習慣です。
Docker Desktop のファイルはどこにありますか。
現行バージョンでは `%LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx` です。古いバージョンでは `docker-desktop-data` という別の WSL ディストリビューションが用意され、ファイルは `%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx` にあります。
sparseVhd を有効にすれば圧縮は不要になりますか。
たいていは不要ですが、スパースディスクの解放は即時ではなく段階的です。非常に大きな削除を行った直後は、手動での圧縮の方が早く結果が出ます。また `sparseVhd` が自動的に適用されるのは、有効化した後に作成されたディスクだけです。
評決
WSL2 と Docker がディスクを圧迫するのは不具合ではなく、仮想ディスクの性質です。手順は単純で、内部を整理し、WSL を停止し、ディスクを圧縮する。この 3 段階でほとんどの開発マシンは一度に 20〜60 GB を取り戻せます。
恒久的な対策として `sparseVhd=true` を有効にし、ビルドキャッシュを定期的に削除してください。ドライブに他に何がたまっているか知りたい場合、Disk Mop の「大きいファイル」と Disk Treemap は、こうした巨大な単一ファイルを数秒で浮かび上がらせます。