我自從將 Docker 都改裝到 WSL 2 之後,磁碟用量日漸增加,發現 WSL 2 的 ext4.vhdx 虛擬硬碟檔案變得非常大,所以又重新研究了一下如何對 WSL 2 的虛擬硬碟進行壓縮,這篇文章就來說明如何正確對 WSL 2 的 ext4.vhdx 虛擬硬碟進行壓縮。

由於 WSL 2 的虛擬硬碟採用動態擴充機制,它會隨著寫入資料而變大,但在刪除資料後不會自動釋放空間回 Windows 系統,因此必須手動執行壓縮 (Compact) 操作。
若要壓縮 WSL 2 或 Docker Desktop 使用的 ext4.vhdx 虛擬硬碟檔案,主要有兩種方式:
-
使用 Hyper-V 的 PowerShell 指令 Optimize-VHD
如果你使用的是 Windows 專業版、企業版或教育版,並且已啟用 Hyper-V 功能,才能使用 Optimize-VHD 指令會更快速且方便。
-
使用 Windows 內建的 Diskpart 工具
這是 Windows 內建的磁碟管理工具,適用於 Windows Home 與 Pro 版本,是最為通用的方法,本篇文章會以這個方法為主。
步驟一:清理 Linux/Docker 內部的資料
在壓縮虛擬硬碟之前,必須先在系統內部釋放空間,標記未使用的區塊。否則,外部工具無法識別哪些空間可以回收。
-
先清除未使用的 Docker 映像檔 (Images)、容器 (Containers) 與快取。
# 清理 BuildKit 的建構快取 (Build Cache)
docker builder prune -a
# 清理整個系統中不被使用的資源 (包含容器、映像檔、網路、快取等)
# 這會刪除所有已停止的容器與未使用的映像檔,請確認後在執行
# docker system prune -a
-
進入 WSL 並清理套件快取,或刪除不需要的大型檔案
# 清理 apt 套件管理器的快取與不需要的套件
sudo apt-get clean
sudo apt-get autoclean
sudo apt-get autoremove
# 刪除 Node.js 的套件快取
npm cache clean --force
yarn cache clean
# 刪除 Rust 的套件快取
rm -rf ~/.cargo/registry/cache/*
# 你可以從 ~/.cache/ 目錄下找到許多可能已經不需要的快取檔案!
這些指令會清除 apt 套件管理器的快取與不需要的套件。
-
從 WSL 標記未使用的區塊
在進行檔案清理之後,建議執行 fstrim 來標記未使用的區塊,此指令會通知底層虛擬化層哪些區塊不再使用。
sudo fstrim -v /

步驟二:確認檔案路徑並關閉 WSL
在操作 ext4.vhdx 檔案之前,必須確保沒有任何處理序 (Process) 正在使用它。
-
找到 ext4.vhdx 的路徑:通常位於使用者的 AppData 資料夾中。
通常檔名都叫做 ext4.vhdx,你可以透過 Everything 快速找到此檔案。
Ubuntu (WSL 2) 常見路徑如下:
- Ubuntu 18.04: "%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"
- Ubuntu 20.04: "%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc\LocalState\ext4.vhdx"
- Ubuntu 22.04: "%LOCALAPPDATA%\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx"
- Ubuntu 24.04: "%LOCALAPPDATA%\wsl{a886d7a7-be06-47f7-bc0f-9c4e00ecd51f}\ext4.vhdx"
請自行將 %LOCALAPPDATA% 替換為實際路徑:C:\Users\USERNAME\AppData\Local
-
確保所有 WSL 實體都已停止運作
你可以用 wsl --list --verbose 指令來確認所有 WSL 實體的狀態,確保它們都是停止 (Stopped) 狀態。
接著你可以透過以下命令完全關閉 WSL 運作中的實體:
wsl --shutdown
然後再執行一次 wsl --list --verbose 命令,確認狀態皆為 Stopped 狀態。
步驟三:執行壓縮
-
以系統管理員身分開啟 PowerShell 或 CMD
-
輸入 diskpart 命令,並按 Enter 進入互動模式
-
依序執行以下指令
選擇虛擬磁碟檔案 (請替換為您的實際檔案路徑)
select vdisk file="C:\Users\USER\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx"
以唯讀模式掛載 (避免資料損壞)
attach vdisk readonly
執行壓縮
compact vdisk
卸載虛擬磁碟
detach vdisk
退出 Diskpart
exit

-
執行完畢後,您應該會發現檔案總管中的 ext4.vhdx 檔案大小已顯著減少。
其他替代方案
若上述方法效果不彰,可以考慮使用 wsl --export 將發行版匯出成 tar 檔,刪除舊環境後,再使用 wsl --import 匯入,這會建立一個全新的、最小化的 vhdx 檔案。
wsl --export Ubuntu-22.04 ubuntu22.04.tar --format tar
wsl --unregister Ubuntu-22.04
wsl --import Ubuntu-22.04 C:\WSL\Ubuntu-22.04\ ubuntu22.04.tar --version 2
這裡的 C:\WSL\Ubuntu-22.04\ 是你想要存放新 WSL 2 環境的路徑,可以自行更改。