WSL2+Docker Desktopの容量掃除と構成の棚卸しメモ
このメモ書きは、Windows上のDocker Desktop(WSL2)がCドライブを圧迫していた件の調査と掃除、およびその過程で整理したDockerの基本と開発環境の構成を記録したものである。
発端
AppData\Local 配下のフォルダ容量を集計したところ、上位はDockerとWSLが占めていた。
| フォルダ | 容量 |
|---|---|
| AppData\Local\Docker | 33.23GB |
| AppData\Local\wsl | 29.95GB |
| AppData\Local\Claude-Data | 9.92GB |
| AppData\Local\Google | 7.49GB |
docker system df -v で内訳を確認した結果、ビルドキャッシュだけで25.01GBに達していた。
docker system df -v
Docker基本の基
Dockerは「Dockerfile → イメージ → コンテナ」の三段構成になっている。
| 用語 | 位置づけ | 例え |
|---|---|---|
| Dockerfile | 環境の作り方を書いたテキスト | レシピ |
| イメージ | Dockerfileをビルドした読み取り専用の完成品 | 冷凍保存した完成料理 |
| コンテナ | イメージを起動した実体 | 温めて食卓に出した状態 |
| ボリューム | コンテナが消えても残すデータ置き場 | 別の保存容器 |
| ビルドキャッシュ | ビルド手順ごとの中間結果 | 下ごしらえの残り |
Dockerfileを「設計図」と呼ぶ人もいればイメージを「設計図」と呼ぶ人もいる。Docker用語としてはDockerfileが手順書、イメージが成果物として区別される。
Dockerの歴史
Dockerは既存のコンテナ技術を使いやすくまとめたものであり、ゼロからの発明ではない。
| 年 | 技術 | 内容 |
|---|---|---|
| 1979 | chroot | ルートディレクトリの差し替え。隔離の元祖 |
| 2000 | FreeBSD jail | プロセス・ネットワーク・ユーザーも隔離 |
| 2004 | Solaris Zones | 同系統の隔離技術 |
| 2005 | OpenVZ | Linuxの本格コンテナ。独自カーネルパッチが必要 |
| 2002〜2008 | namespaces / cgroups | Linuxカーネルに隔離と資源制限の部品が入る |
| 2008 | LXC | パッチ不要の標準Linuxコンテナ。初期DockerはLXCを利用 |
| 2013 | Docker | イメージ形式・Dockerfile・レイヤー・Docker Hubで普及 |
| 2015 | OCI | コンテナ規格の標準化 |
Dockerが変えたのは技術そのものではなく使い勝手である。ただし「誰でも使える」はLXCとの比較での話であり、Dockerfileを書く側には今も相応の前提知識が求められる。
project_Aイメージの中身
docker history でレイヤーごとのサイズを確認した。
docker history project_a:latest
| サイズ | 内容 |
|---|---|
| 697MB | Python仮想環境(bm27系AIライブラリ) |
| 547MB | 追加したOSパッケージ(apt-get) |
| 366MB | 公式PHPイメージの標準部分 |
| 145MB | Denoランタイム |
| 104MB | Python仮想環境 |
| 98.8MB | ONNXモデルファイル |
| 87.7MB | ベースOS(Debian trixie) |
イメージ全体は3.11GBである。マルチステージビルドは既に使われており、肥大の主因は音ゲー譜面自動生成ツールの開発で試したAIモデル群を丸ごと同梱していることにある。モデル選定が終わった段階で、落選モデルとその依存ライブラリを外すのが軽量化の本命になる。
掃除の手順
Docker内のゴミを捨てる
docker builder prune -a
docker image prune
どちらも稼働中のコンテナが使うものは消さない仕様である。実行後、Build Cacheは0Bになった。
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 2 3.283GB 3.283GB (100%)
Build Cache 0 0 0B 0B
Ubuntu内のゴミを捨てる
ホーム配下では .npm が5.4GBを占めていた。
npm cache clean --force
rm -rf ~/.cache/*
npm cache clean --force 実行時の Recommended protections disabled. は、安全確認を省略したという通知である。npmの仕様上 --force は必須で、キャッシュは次回のinstall時に再取得される。
Windows側の仮想ディスクを縮める
pruneしてもCドライブの空き容量は増えなかった。WSL2の仮想ディスク(vhdx)は膨らむのは自動、縮むのは手動である。
対象のvhdxは以下のとおりである。
| ファイル | サイズ | 正体 |
|---|---|---|
| Docker\wsl\disk\docker_data.vhdx | 32.83GB | Dockerのデータ本体 |
| Docker\wsl\main\ext4.vhdx | 0.1GB | docker-desktopディストリ本体 |
| wsl{c6d4...}\ext4.vhdx | 27.76GB | 開発用ディストリ(Ubuntuと推定) |
| wsl{565a...}\ext4.vhdx | 2.19GB | 未使用ディストリ(AlmaLinux-9と推定) |
Docker Desktopを終了し、管理者PowerShellで以下を実行した。
wsl --shutdown
diskpart
select vdisk file="C:\Users\PC\AppData\Local\Docker\wsl\disk\docker_data.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit
compact完了後、Cドライブの空き容量が回復した。
vhdxはVirtual Hard Disk v2の略で、ディスク1台分を1個のファイルにしたものである。df -h / で表示される1007Gは上限値であり、実際に確保されている容量ではない。Ubuntuの実使用量は12GBであったのに対し、vhdxは27.76GBに膨らんだままになっていた。
引っかかった点
順番を間違えた
pruneより先に wsl --shutdown を実行したため、Docker Desktopが停止した状態になり、docker コマンドが通らなくなった。正しい順番はprune → Docker Desktop終了 → shutdown → compactである。
shutdown後にコンテナが片方だけ戻らなかった
docker ps -a で確認すると、Webサーバー側がExitedになっていた。
docker start project_a-web
docker ps
docker start は成功時にコンテナ名を返すだけで、成功メッセージは出ない。状態は docker ps のSTATUS欄で判断する。
| STATUS | 意味 |
|---|---|
| Up 59 seconds | 稼働中(起動から59秒経過) |
| Exited (127) | 停止 |
Docker Desktopが起動しない
compact後にDocker Desktopを起動したところ、「Starting the Docker Engine...」のまま5分以上進まなかった。wsl -l -v ではdocker-desktopがRunningであるにもかかわらず、Ubuntuから docker が見つからない状態が続いた。Quitも効かなかったため、タスクマネージャーでDocker Desktop関連プロセスを強制終了し、wsl --shutdown 後に10秒ほど待って再起動した。
強制終了で問題になるのはDBなどに書き込み中の場合である。今回はボリュームが空で、イメージもDockerfileから再ビルドでき、本番はVPSで稼働しているため実害はない。
PowerShellでのクォート崩れ
docker inspect project_a-app --format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}'
PowerShellでは内側のダブルクォートが解釈され function "com" not defined になった。Ubuntu側で実行するか、エスケープして回避する。
docker inspect project_a-app --format "{{index .Config.Labels \"com.docker.compose.project.working_dir\"}}"
構成の棚卸し
composeのラベルからプロジェクトの場所を特定した。本物のソースは /var/www/html/project_A にあり、Laravel+Vite+Tailwind+Pythonの構成になっている。
| 場所 | 中身 | 状態 | 当初の目的 |
|---|---|---|---|
| /var/www/html/project_A | Dockerfile, compose.yaml, Laravel, python | 使用中 | 本番アプリの開発 |
| ~/vscd_projects/vol01_app | AlmaLinux用Dockerfile, test.php | 未使用 | 本番と同じAlmaでPHPを動かす試作 |
| ~/vscd_projects/vol02_app | main.py, venv, wav, mid | 未使用 | MIDI解析の実験。譜面生成の土台 |
| ~/bm27-compare | 比較用スクリプト | 未使用 | AIモデルの性能比較 |
| AlmaLinux-9 (WSL) | ディストリ | 未使用 | 開発も本番もAlmaで揃える計画 |
経緯としては、当初は開発も本番もAlmaLinuxで揃えようとしたが、AI・音声系ライブラリがAlma上で動かず開発をUbuntuへ移した。その後Docker化したことで、本番VPSのOSがAlmaのままでもコンテナ内はDebianで統一され、OS差異の問題はDockerで解消している。
コンテナがwebとappの2つに分かれているのは「1コンテナ1役割」の原則による。webはApacheでブラウザからのアクセスを受け、PHPの処理だけをappのphp-fpm(ポート9000)に渡している。今回webだけが停止した際もappは無事であり、分割の利点が表れている。
用語
WSL2:Windows上で軽量なLinux VMを動かす仕組み。
docker-desktop:Docker Desktopが自動で作る裏方のLinuxディストリ。Docker Engineはここで動き、Ubuntuの docker コマンドはWSL integrationを通じてここに届く。
vhdx:仮想ハードディスクを1個のファイルにしたもの。動的に拡張され、自動では縮まない。
prune:未使用のDockerリソースを削除するコマンド群。
compact:diskpartでvhdxの空き領域を詰めてファイルを小さくする操作。
Up / Exited:コンテナの稼働中 / 停止の状態表示。
compose:複数コンテナをまとめて定義・起動する仕組み。設定ファイルは compose.yaml。
余談
Docker Desktopは必須ではない:Ubuntuの中にDocker Engineを直接インストールする構成も取れる。起動が速く常駐アプリも不要になる一方、既存のイメージやコンテナは引き継がれず再ビルドになる。今回のような起動トラブルが続く場合の乗り換え候補である。
ファイルの置き場所:/mnt/c 配下やSamba越しのファイルで開発すると、OS境界をまたぐため大量の小ファイルの扱いが極端に遅くなる。ソースはUbuntu内に置き、Windowsからは \\wsl$\Ubuntu\... やVSCodeのRemote WSLで触るのが速い。
本番VPS:デプロイのたびにpruneしており、手元のような25GBの蓄積は起きていない。手元ではビルドを繰り返しながらpruneしていなかったことが差になっている。
まとめ
| 論点 | 結論 |
|---|---|
| 容量圧迫の原因 | Dockerのビルドキャッシュ25GBとvhdxの膨張 |
| pruneで空き容量が増えない理由 | vhdxは自動で縮まないため、compactが別途必要 |
| 掃除の正しい順番 | prune → Docker Desktop終了 → wsl --shutdown → compact |
| project_Aイメージが重い理由 | 試行錯誤したAIモデル群とPython環境の同梱 |
| 軽量化の方針 | 採用モデルの依存だけに絞り、モデルの外出しも検討 |
| コンテナの状態確認 | docker ps のSTATUS欄でUp / Exitedを見る |
| Docker Desktopが固まった場合 | プロセス強制終了 → wsl --shutdown → 再起動 |
| 未使用の資産 | vol01_app, vol02_app, bm27-compare, AlmaLinux-9。いずれも小さく急いで消す必要はない |
| Dockerを入れた意味 | 開発Ubuntuと本番Almaの差異をコンテナ内のDebianで吸収している |
あとがき
Dockerの基本、WSLの仕組み、過去の実験フォルダの正体まで掘り返す作業になった。vol02_appの main.py を開いてMIDI解析をしていた記憶がよみがえったのは収穫である。次の課題は、モデル選定が確定した段階でのproject_Aイメージの軽量化と、AlmaLinux-9ディストリの処分判断になる。