Skip to main content
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