👐

WSL2+Dockerによって圧迫されている容量を解放する方法(vhdxファイルの最適化)

に公開

WSL2ではvhdxという仮想ハードディスク形式が用いられています。最大64TB(記事執筆時点ではWSL2用vhdxファイルのデフォルト設定は最大1TB)まで自動で拡張しながら容量を確保してくれますが、一方でWSL2内でファイルを削除しても確保された容量が自動で小さくなってはくれません。そのため、WSL2では手動で容量を解放(最適化)してあげる必要があるので、良く使っている方法を備忘録的に残しておきます。Powershellのコマンドにoptimize-vhdがなかった方(Windows Homeを使っている方)向けの記事です。

Dockerがため込んでいるデータをまるっと削除(WSL2内で実行)

使用中のものでも問答無用で消してしまうので、消したくないコンテナやイメージがある方は適宜コマンドを変更してください。

docker rm -f $(docker ps -aq) # 全コンテナ強制削除
docker rmi -f $(docker images -aq) # 全イメージ強制削除
docker volume rm $(docker volume ls -q) # 全ボリューム削除
docker builder prune # 全ビルドキャッシュ削除
docker system prune # ネットワークなど、残りものを削除

WSL2が使用しているvhdxファイルの場所を特定(PowerShellで実行)

Ubuntuの部分は使用しているディストリビューションに合わせて変更してください。

Get-AppxPackage -Name "*Ubuntu*"

Microsoft Store経由でインストールされたアプリの内、Ubuntuが名前に入っているものの情報が表示されます。(私の環境の場合、NameがCanonicalGroupLimited.Ubuntu20.04onWindowsのものも表示されましたが省略しています)

Name              : CanonicalGroupLimited.UbuntuonWindows
Publisher         : CN=23596F84-C3EA-4CD8-A7DF-550DCE37BCD0
Architecture      : X64
ResourceId        :
Version           : 2004.2022.1.0
PackageFullName   : CanonicalGroupLimited.UbuntuonWindows_2004.2022.1.0_x64__79rhkp1fndgsc
InstallLocation   : C:\Program Files\WindowsApps\CanonicalGroupLimited.UbuntuonWindows_2004.2022.1.0_x64__79rhkp1fndgsc
IsFramework       : False
PackageFamilyName : CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc
PublisherId       : 79rhkp1fndgsc
IsResourcePackage : False
IsBundle          : False
IsDevelopmentMode : False
NonRemovable      : False
Dependencies      : {CanonicalGroupLimited.UbuntuonWindows_2004.2022.1.0_neutral_split.scale-100_79rhkp1fndgsc, CanonicalGroupLimited.UbuntuonWindows_2004.2022.1.0_neutral_split.scale-125_79rhkp1fndgsc}
IsPartiallyStaged : False
SignatureKind     : Store
Status            : Ok

表示されているPackageFamilyNameに対して、

C:\Users\{ユーザー名}\AppData\Local\Packages\{表示されたPackageFamilyName}\LocalState\ext4.vhdx

がWSL2で使用しているvhdxファイルのパスになります。以降で使うので、パスはクリップボードにコピーしておいてください。
複数表示されている場合は、上記パスを見に行ってvhdxファイルが存在するかどうかを確認するのが手っ取り早いと思います。どちらか一方にのみあるはず…。

WSL2をシャットダウン&最新版にアップデート(PowerShellで実行)

WSL2がディスク使用中にvhdxファイルを操作してしまうと破損する恐れがあるので、WSL2をシャットダウンして安全に操作できるようにします。またこの際、ついでに私は念のためWSL2のアップデートも行っています(WSL2のカーネルが古いことが原因で、vhdxファイルを触った後に読み込めないことがあるそうです)。
また、もし以降の操作が不安な方は、この段階でvhdxファイルをコピーしてバックアップを取っておくと安心です。

wsl --shutdown
wsl --update

diskpartを起動(PowerShellで実行)

diskpartを起動します。環境次第かもしれませんが、私の場合PowerShellを管理者権限で実行してからdiskpartを行った際、compact vdiskの途中で全く進まなくなった経験があります。なので毎回、PowerShellは通常ユーザー権限で実行して、diskpartコマンドを打った後に出てくる「このアプリがデバイスに変更を加えることを許可しますか?」に「はい」と答えています。

diskpart

vhdxファイルを最適化(diskpart内で実行)

あとは最適化したいvhdxファイルを選択して最適化するだけです。私の環境ではcompact vdiskに10~15分ほど時間がかかりました。定期的にやっていますが、多い時で50GB、少ない時でも20GBくらいCドライブの容量が解放されて嬉しくなります。

select vdisk file={vhdxファイルのパス}
attach vdisk readonly # やらなくてもよいが、読み取り専用にした方が圧倒的に早い
compact vdisk
detach vdisk
exit

参考

https://qiita.com/siruku6/items/c91a40d460095013540d
https://qiita.com/TsuyoshiUshio@github/items/7a745582bbcd35062430

Discussion