2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dockerで肥大化したWSLを小さくする話

2
Last updated at Posted at 2026-08-21

【目的】
.devcontainerをリビルドしていたら立ち上がらなかった
エラーメッセージを見ると「○○のファイルはread-only」ですといったエラーだったので嫌な予感がして本体容量を見ると空き容量が32MBだった。
1TBのPCなのに空きが32MBだった。

こんなものはdockerのイメージかキャッシュか何か知らんが古いのが大量に残ってるしかない!ということで大掃除したお話

【環境】
Windows11
WSL2
Ubuntu 24.04 LTS
Docker Engine(WSL2上のUbuntuに直接インストール。Docker Desktopは未使用)

【構成】
WSL2上のDocker Engineを使用し、Dev Containerでシステムを起動・開発

手順

簡単にまとめると
dockerの不要物を削除 → WSLの圧縮
です。

実際にやった手順としては

  1. PCの空き容量の確認
  2. WSLの空き容量の確認
  3. dockerの不要物を削除
  4. WSLの圧縮

になります

現在の空き容量の確認

readonlyエラーは容量不足で書き込みが一切できていない可能性が高いと思ったのでまずは
設定>システム>ストレージで空き容量を確認したところ、空きが32MBだった。
インストールされているアプリで900G以上使っていたので詳細を見たところ、最大でも5Gに満たないアプリがあるだけで合計しても100Gもいかないくらいだったので、wslの肥大化が原因であることをほぼ確証する

WSLの空き容量の確認

powerShell
$ wsl --shutdown

とりあえずWSLをすべてシャットダウンする。

powerShell
$ Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss |
 ForEach-Object {
     $name = $_.GetValue("DistributionName")
     $base = $_.GetValue("BasePath")
     $vhd  = Join-Path $base "ext4.vhdx"

     [PSCustomObject]@{
         Distribution = $name
         VhdPath      = $vhd
         Exists       = Test-Path $vhd
         SizeGB       = if (Test-Path $vhd) {
             [math]::Round((Get-Item $vhd).Length / 1GB, 1)
         } else {
             $null
         }
     }
 }

このコマンドでディストリビューション名、vhdxのパス、容量を取得する。
実行結果はこんな感じ

powerShell
$ Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss |
  ForEach-Object {
      $name = $_.GetValue("DistributionName")
      $base = $_.GetValue("BasePath")
      $vhd  = Join-Path $base "ext4.vhdx"

      [PSCustomObject]@{
          Distribution = $name
          VhdPath      = $vhd
          Exists       = Test-Path $vhd
          SizeGB       = if (Test-Path $vhd) {
              [math]::Round((Get-Item $vhd).Length / 1GB, 1)
          } else {
              $null
          }
      }
  }

Distribution VhdPath                                Exists SizeGB
------------ -------                                                                                    ------ ------
Ubuntu-24.04 C:\Users\【YOURE FILE PATH】\ext4.vhdx   True   814.2

これでUbuntu-24.04だけで814Gも使ってることがわかります。
なのでこれがPCの容量圧迫の原因として、ディストリビューションの中身を整理します。

ここで取得したVhdPath(今回はC:\Users\【YOURE FILE PATH】\ext4.vhdx)の圧縮処理を行うのでVhdPathは記録しておく(後で再取得でもOK)

dockerのキャッシュ類を削除

今回はもうめんどくさかったので全部消しましたが、docker system dfコマンドで何が原因かを確かめてから消したほうがいいと思います。

WSL
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          5         4         10.27GB   40.24kB (0%)
Containers      4         4         793.9MB   0B (0%)
Local Volumes   5         4         6.725GB   147B (0%)
Build Cache     133       0         19.11GB   15.54GB

キャッシュが増えていたら

WSL
$ docker builder prune

でキャッシュだけ消せるのでそのほうがいいかと思います
上記の状態でもキャッシュを消すと

WSL
$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          5         4         10.27GB   40.24kB (0%)
Containers      4         4         793.9MB   0B (0%)
Local Volumes   5         4         6.725GB   147B (0%)
Build Cache     27        0         3.573GB   0B

になったので十分効果はあると思います

イメージが増えているなら

WSL
docker image prune

でイメージ削除ができます。
docker image pruneだけなら dangling imageだけ、
docker image prune -aなら 未使用イメージ全部、
docker image prune -a --filter "until=168h"なら作成から168時間以上経過した未使用イメージだけ
を削除できます。

dangling image = タグが付いていない不要候補のイメージ
unused image(未使用イメージ) = タグが付いていても現在どのコンテナからも使われていないイメージ
なので状況に応じて消したいように消してください

WSLの容量開放指示

WSL
$ sudo fstrim -av

sudo fstrim -avは、簡単に言うとWSL上のもう使っていない領域を示すためのコマンドです。
今回はDockerデータを大量削除したあとにext4.vhdx(WSLのディストリビューションのファイルシステム全体を保存してる仮想ディスクファイル)を縮小しやすくするために実行しました。
実行すると850 GiB (912680550400 bytes) trimmedのように表示されて、どれだけの領域が解放できるかがわかります。

powerShell
$ wsl --shutdown

WSLはシャットダウンしておく。

WSLの容量開放処理

powerShell
$ diskpart

これを叩くとアカウント制御の警告が出るがOKしてdiskpartに入る。
以下のような新しいターミナルが開かれる

DISKPART
Microsoft DiskPart バージョン 10.0.26100.1150

Copyright (C) Microsoft Corporation.
コンピューター: YOURE_PC_NAME

DISKPART>

diskpart内でvdiskの圧縮を行う

DISKPART
$ select vdisk file="C:\Users\【YOURE FILE PATH】\ext4.vhdx"
$ detail vdisk
$ compact vdisk

select~でvdiskを選択、
detail~でvdiskの詳細確認(念のため)
compact~でvdiskを縮小
です

終わるまで時間がかかるけど待機します。

今回は30分以上たっても進捗が100%にならず、

powerShell
$ Get-PSDrive C | Select-Object Name,
     @{Name="UsedGB";Expression={[math]::Round($_.Used / 1GB, 1)}},
     @{Name="FreeGB";Expression={[math]::Round($_.Free / 1GB, 1)}}

Name UsedGB FreeGB
---- ------ ------
C     154.2  774.6

である程度開放されていることは確認し、

powerShell
$ Get-Item $vhd | Select-Object FullName,
     @{Name="SizeGB";Expression={[math]::Round($_.Length / 1GB, 1)}},
     LastWriteTime

FullName                              SizeGB LastWriteTime
--------                                                                                   ------ -------------
C:\Users\【YOURE FILE PATH】\ext4.vhdx   38.9 2026/08/20 22:01:01

でvhdx小さくなってること、LastWriteTimeが20分以上前であることを確認したのでもう処理自体は終わっていて進捗が100%にならないだけと判断しました。

Ctrl +Cで無理やり落とす前にDiskPartの画面でenterを押してみたら無事進捗が100%になったので作業完了としました

まとめ

今回は850Gくらい開放できました。
docker使うときはめっちゃ容量食うから定期的にきれいにしようねという教訓でした。

学び

毎日退勤前に

WSL
$ docker builder prune

は流しておこうね!!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?