HOWTO · Docker

如何將主機目錄掛載至 Docker 容器

本文示範如何將主機目錄掛載到 Docker 容器。

本頁內容

**繫結掛載(bind mount)**會將主機上的目錄連接到 Docker 容器內的路徑。當容器需要讀取或更新主機上的特定目錄時,例如開發期間使用的原始碼,就可以使用繫結掛載。以下範例會先在主機上建立目錄和檔案,再示範如何透過 Docker 指令,讓 Alpine shell 存取該目錄。文中的 Docker 指令僅供說明,本次撰寫並未實際執行。

使用繫結掛載將主機目錄掛載到 Docker 容器

繫結掛載會將指定的主機路徑呈現在容器內的路徑。它與由 Docker 管理的磁碟區不同,來源是主機上的特定位置。對該目錄中的檔案所做的變更,也會反映在容器的掛載點。應用程式可以看到這些變更,但只有在應用程式會監看檔案或重新載入檔案時,才會自動載入變更。

使用 -v 或 --volume 掛載主機目錄

這個 Python 範例會在主機上建立名為 site 的目錄,在其中寫入檔案,並印出檔名。請在準備啟動 Docker 的目錄中執行:

from pathlib import Path

site = Path("site")
site.mkdir(exist_ok=True)
(site / "hello.txt").write_text("Hello from the host.\n")
print("\n".join(sorted(path.name for path in site.iterdir())))
hello.txt

接著可在容器的 /site 查看主機上的檔案。啟動容器時使用 docker run --rm -it --volume "$PWD/site:/site" alpine:3.20 sh。磁碟區值的格式為 主機路徑:容器路徑[:選項]:$PWD/site 是主機目錄,/site 是它在容器中顯示的位置;加上選用的 ro 後綴即可將掛載設為唯讀。簡寫旗標 -v 與完整旗標 --volume 使用相同語法,因此 -v "$PWD/site:/site:ro" 代表唯讀掛載。

容器 shell 執行期間,可在主機上用 touch "$PWD/site/mounted-check.txt" 建立新的檔案,再於容器提示字元輸入 ls /site,確認清單中出現 mounted-check.txt。掛載可寫入時,在 /site 建立的檔案也會寫入主機目錄。若使用唯讀掛載,容器可以讀取檔案,但無法透過此掛載修改檔案。

使用 -v 或 --volume 時,若主機來源目錄不存在,Docker 會將它建立為目錄。啟動容器前請確認主機路徑正確;路徑打錯可能會建立新的空目錄,讓人誤以為原本預期的檔案不見了。

使用 --mount 掛載主機目錄

--mount 會以逗號分隔的鍵值欄位指定各項設定。若要使用相同範例,可執行 docker run --rm -it --mount "type=bind,source=$PWD/site,target=/site" alpine:3.20 sh。type=bind 指定繫結掛載,source 是主機目錄,target 則是該目錄在容器中的路徑。在掛載欄位中加入 readonly,即可禁止透過此掛載寫入。欄位順序不會決定哪個路徑是來源或目標;用途由欄位名稱決定。

與 -v 和 --volume 不同,若繫結掛載的來源不存在,--mount 會回報錯誤。請先建立並確認主機目錄,再啟動容器。若路徑包含逗號,使用逗號分隔的掛載語法時需要特別留意;請改用合適的主機路徑,或查閱適用於你平台的 Docker 掛載語法。

繫結掛載會讓容器存取選定的主機路徑。只掛載工作負載所需的目錄,避免暴露敏感檔案;若容器不需要寫入,請使用唯讀掛載。主機路徑分享方式和權限也可能取決於系統上的 Docker 設定。

結論

若要使用精簡的冒號分隔格式,可選擇 -v 或 --volume;若偏好明確的鍵值欄位,則可使用 --mount。兩者都能讓容器存取主機目錄,但 -v 會建立不存在的來源目錄,--mount 則要求來源已存在。當容器需要使用主機上的特定路徑時,請選擇繫結掛載。若是應用程式資料,且希望由 Docker 管理而不依賴特定主機目錄,Docker 管理的磁碟區通常更合適。