Docker Volume bind mount
容器一刪,寫進它「可寫層」的東西就沒了。要留住資料,得把資料放到容器之外。這頁把四種落點講清楚。撥下面四種模式,看資料實際落在哪、容器刪掉還在不在:
不掛載時資料在容器可寫層
容器在唯讀映像層之上有一層「可寫層」。沒掛載時,寫進去的檔案都落在這層,走 copy-on-write(CoW):改一個既有檔案時,先把整個檔案從唯讀層複製到可寫層,再改副本。
- 改一個 1 GB 檔案的一個 byte,也要先整檔複製,寫入密集會明顯變慢。
- 可寫層跟著容器生命週期,
docker rm 就全沒。
所以資料庫、需要保留的資料、大量 I/O 的工作負載,都不該只待在容器可寫層。
三種掛載比較
具名 volume 的實體位置
Linux 上:
WSL 2 後端下,這條路徑在 docker-desktop-data 這個 WSL 虛擬機裡,不在 Windows 檔案系統,從檔案總管直接點不進去。要讀 volume 內容:
bind mount:-v 與 --mount
兩種語法做同一件事,但 --mount 語義明確、官方建議優先:
-v 的相對路徑雷:-v mydata:/app/data(無斜線開頭)會被當成「建一個叫 mydata 的具名 volume」,不是 bind mount。要確定是 bind mount,用絕對路徑或明確的 --mount type=bind。
匿名 volume 與 Dockerfile VOLUME 的雷
-v 只給容器路徑、不給名稱,會建一個隨機 UUID 的匿名 volume。Dockerfile 的 VOLUME 指令在 docker run 時也會自動建匿名 volume 掛到那個路徑。
docker run 時匿名 volume 掛到 /app,遮蔽掉容器層裡 npm install 裝好的 node_modules,應用就跑不起來。對策:VOLUME 別宣告在會被遮蔽的路徑,或乾脆不用 VOLUME,改在 docker run / Compose 顯式掛載。
容器不帶 --rm 刪掉後,匿名 volume 會殘留成 dangling volume,用 docker volume prune 清。
docker volume 指令
WSL 2 的掛載效能(重要)
高 I/O 的資料(程式碼、node_modules、資料庫檔)要放在 WSL 2 的 Linux 檔案系統再 bind mount,不要從 /mnt/c(Windows 路徑)掛載:
官方說明:從 Windows 檔案系統 bind mount 效能明顯較差,而且 inotify 事件只在 Linux 檔案系統上有效,掛 /mnt/c 會讓 hot reload(Vite、webpack、nodemon)收不到檔案變更而失效。高 I/O 場景優先用具名 volume 或從 WSL 2 Linux 側出發的 bind mount。
接下來
- 效能設定:
docker-desktop-data VHDX 怎麼看大小、搬移。
- Docker Compose:在 compose.yaml 裡掛 volume 與 bind mount。
官方參考:docs.docker.com/engine/storage