Docker 數據持久化:Volumes 與 Bind Mounts

在之前的章節中我們提到,容器是「隨取隨用、隨時可刪」的。如果我們在容器內寫入資料(例如:MySQL 的資料庫檔案、使用者的上傳圖片),一旦容器被刪除,這些資料也會隨之消失。

為了保存重要數據,Docker 提供了三種主要的方式來將資料存儲在容器外的「主機」上。

三種掛載方式概覽

1. Docker Volumes (推薦)

由 Docker 引擎完全管理的儲存空間。資料儲存在主機上的特定目錄(Linux 通常在 /var/lib/docker/volumes/),但你不需要知道具體路徑,直接透過 Docker 指令管理。

  • 優點:效能好、方便備份與遷移、受 Docker 安全隔離。

2. Bind Mounts

將主機上「任意指定」的目錄或檔案,直接掛載到容器內。

  • 優點:適合開發環境(例如將程式碼目錄掛載進去,修改存檔後容器立即生效)。
  • 缺點:過於依賴主機的目錄結構,不可跨平台遷移。

3. tmpfs Mounts

資料只存在主機的「記憶體」中,不會寫入硬碟。

  • 優點:讀寫極快,且不會在主機留下紀錄(適合存放敏感密鑰或快取)。

實戰:使用 Docker Volumes

1. 建立 Volume

docker volume create my-db-data

2. 查看 Volume 列表

docker volume ls

3. 將 Volume 掛載到容器

我們以部署一個資料庫為例:

docker run -d \
  --name my-mysql \
  -e MYSQL_ROOT_PASSWORD=password \
  -v my-db-data:/var/lib/mysql \
  mysql:8.0

語法說明: -v [Volume名稱]:[容器內路徑]

4. 驗證持久化

即使你刪除了這個 MySQL 容器,下次啟動一個新容器並掛載同一個 my-db-data,你的資料庫內容依然會在。

實戰:使用 Bind Mounts

這在本地開發 Node.js 或 Python 專案時最常用。

docker run -d \
  -p 8080:80 \
  -v $(pwd)/html:/usr/share/nginx/html \
  nginx

語法說明: -v [主機絕對路徑]:[容器內路徑]

  • $(pwd):代表目前所在目錄。
  • 這會將主機 html/ 資料夾的內容直接蓋掉 Nginx 的預設頁面。

Volumes vs Bind Mounts 怎麼選?

特性Docker VolumesBind Mounts
主機路徑由 Docker 管理 (隱形成員)由使用者自定義 (明確路徑)
效能
可移植性高 (可打包遷移)低 (受限於主機目錄)
主要用途資料庫、日誌、持久化檔案開源專案原始碼、設定檔對應
安全性較好 (由 Docker 權限管理)較差 (容器可直接修改主機敏感檔案)

清理未使用的資料卷

Volume 不會隨著容器刪除而自動消失。長時間下來會佔用大量硬碟空間。

# 查看有哪些 Volume 沒在用
docker volume ls -f dangling=true

# 大掃除:刪除所有未使用的 Volume
docker volume prune
docker system prune 預設是不會刪除 Volume 的,因為資料通常是無價的。若要同時刪除 Volume,需加上 --volumes 參數。

掌握了數據持久化,你的 Docker 應用程式就具有了正式營運的基礎。