清理 Mac 上的 Docker 而不丟失資料
Docker Desktop 的映像檔、容器可寫層、建置快取和資料卷都放在 Linux 虛擬磁碟中,很容易佔用幾十 GB。建置快取通常能重建,資料庫卷卻可能是重要資料的唯一副本,因此 Docker 自己的清單比範圍最大的 prune 指令更適合作為起點。
為什麼空間沒有立刻回來
Docker Desktop 在 macOS 上執行 Linux 虛擬機,資料通常保存在疏鬆虛擬磁碟 Docker.raw 中。它的 Mac 儲存空間說明給出了入口:「Docker Desktop > Settings > Resources > Advanced」。這裡能看到位置、上限和實際佔用,也能安全移動虛擬磁碟,直接用 Finder 搬移可能破壞設定。
疏鬆檔案的邏輯上限可能很大,實際配置卻小得多,所以 ls -lh 不能代表真實佔用,Docker 內部統計更接近各類物件的實際情況:
docker system df -v
詳細檢視會分開列出映像檔、容器、資料卷和建置快取。「Reclaimable」只表示 Docker 沒發現目前參照,並不能判斷之後是否還會用到已停止的容器、舊映像檔或資料卷,docker ps -a 和 docker volume ls 可以補上這部分背景。
從範圍最小的清理開始
直接刪除虛擬磁碟檔案等同於丟掉整個 Docker 環境,依類別從 Docker 內部回收更容易控制範圍:
docker builder prune --filter until=168h
docker image prune
docker container prune
第一條移除符合篩選條件的七天前未使用建置快取,可依自己的工作週期調整。後兩條會在刪除懸空映像檔和已停止容器前確認。prune 不經過垃圾桶,也無法復原;停止的容器仍可能有唯一的可寫層資料,懸空映像檔也未必能重新取得,確認不再需要或已有可驗證的備份後再繼續。每一步後重新執行 docker system df -v,看實際回收了什麼。
Docker 的清理說明把 docker system prune 定義為範圍更廣的便捷指令。加入 -a 會刪除所有未使用的映像檔,不只是懸空層,加入 --volumes 還會處理未使用的匿名資料卷,其中可能有資料庫和其他狀態。
docker system prune -a --volumes 的範圍很廣,尤其會觸及可能保存資料庫的資料卷。卷名、標籤和歸屬可以先這樣查看:
docker volume ls
docker volume inspect <volume-name>
Compose 資料卷通常帶有專案與服務標籤。確認所屬專案後,優先用資料庫本身的工具匯出資料;做檔案層級備份前先停止寫入,並檢查備份能否還原,再刪除存有不可重建資料的資料卷。
讓虛擬磁碟歸還實體空間
prune 會先在 Linux 檔案系統內部釋放區塊,macOS 不一定同時拿回空間。目前 Docker 文件說明,Docker.raw 通常會在數秒內歸還符合條件的區塊,舊式 Docker.qcow2 依賴背景行程,可能要幾分鐘。
這裡更有意義的是重新測量實體佔用,而不是看邏輯上限。回復原廠設定也不是壓縮,它會銷毀本機容器、映像檔、資料卷和設定,只適合已經決定丟棄整個環境、並匯出重要資料的情況。
Docker.raw 為什麼只增不減
Docker.raw 是 Linux 虛擬機的疏鬆磁碟。客體系統寫入時它會增長,刪除物件時則先把客體檔案系統中的區塊標為空閒。只有客體發出 TRIM 或 discard,Docker Desktop 再執行相應回收,macOS 才能拿回符合條件的實體區塊。時間取決於 Docker Desktop 版本和磁碟映像實作。
因此,要分別測量 Docker 內部邏輯空間和 macOS 實體容量。直接刪除 Docker.raw 等同於銷毀整個 Docker 環境。
磁碟地圖能幫上什麼
Mole 的「分析」頁可以找出虛擬磁碟及其實體佔用,Docker 命令列則負責判斷內部物件的參照關係。前者回答空間在哪裡,後者回答裡面是什麼。
安全的操作順序
一個較容易複核的順序是執行 docker system df -v,確認舊專案和有狀態的資料卷,匯出唯一資料,再逐類清理,並在每一步複查 Docker 統計和 macOS 容量。最容易安全回收的通常是舊建置快取,不是身分不明的資料卷。