與容器共享本機檔案
說明
每個容器都具備其運作所需的一切,無需依賴主機上任何預先安裝的相依性。由於容器在隔離環境中執行,因此它們對主機和其他容器的影響極小。這種隔離性帶來了一個主要優點:容器可將與主機系統和其他容器的衝突降至最低。然而,這種隔離性也意味著容器預設情況下無法直接存取主機上的資料。
想像一下,您有一個 Web 應用程式容器需要存取儲存在主機系統檔案中的設定。此檔案可能包含敏感資料,例如資料庫憑證或 API 金鑰。將此類敏感資訊直接儲存在容器映像檔中會造成安全風險,尤其是在共享映像檔時。為了因應此挑戰,Docker 提供了橋接容器隔離性和主機資料之間差距的儲存選項。
Docker 提供了兩個主要的儲存選項,用於保存資料並在主機與容器之間共享檔案:磁碟區和繫結掛載。
磁碟區與繫結掛載的比較
如果您希望確保容器內產生或修改的資料在容器停止執行後仍然存在,您應該選擇磁碟區。請參閱保存容器資料以深入瞭解磁碟區及其使用案例。
如果您希望將主機系統上的特定檔案或目錄直接與容器共享,例如設定檔或開發程式碼,則應使用繫結掛載。這就像在主機與容器之間開啟一個直接的通道以進行共享。繫結掛載非常適合開發環境,在這種環境中,主機與容器之間的即時檔案存取和共享至關重要。
在主機與容器之間共享檔案
搭配 `docker run` 命令使用的 `-v`(或 `--volume`)和 `--mount` 旗標都允許您在本機電腦(主機)和 Docker 容器之間共享檔案或目錄。然而,它們在行為和用法上存在一些關鍵差異。
`-v` 旗標更簡單,更便於執行基本的磁碟區或繫結掛載操作。如果在使用 `-v` 或 `--volume` 時主機位置不存在,則會自動建立一個目錄。
假設您是一位正在開發專案的開發人員。您的開發機器上有一個存放程式碼的原始碼目錄。當您編譯或建置程式碼時,產生的成品(已編譯的程式碼、可執行檔、映像檔等)會儲存在原始碼目錄中的一個單獨子目錄。在以下範例中,此子目錄為 `/HOST/PATH`。現在,您希望在執行應用程式的 Docker 容器內可以存取這些建置成品。此外,您希望容器在您重新建置程式碼時自動存取最新的建置成品。
以下是如何使用 `docker run` 啟動容器並使用繫結掛載將其映射到容器檔案位置的方法。
$ docker run -v /HOST/PATH:/CONTAINER/PATH -it nginx
`--mount` 旗標提供了更進階的功能和更精細的控制,使其適用於複雜的掛載場景或生產環境部署。如果您使用 `--mount` 來繫結掛載 Docker 主機上尚不存在的檔案或目錄,`docker run` 命令不會自動建立它,而是會產生錯誤。
$ docker run --mount type=bind,source=/HOST/PATH,target=/CONTAINER/PATH,readonly nginx
**注意**
Docker 建議使用 `--mount` 語法而非 `-v`。它可以更好地控制掛載過程,並避免因目錄遺失而產生的潛在問題。
Docker 存取主機檔案的檔案權限
使用繫結掛載時,確保 Docker 具有存取主機目錄的必要權限至關重要。要授予讀取/寫入權限,您可以在建立容器期間,搭配 `-v` 或 `--mount` 旗標使用 `:ro` 旗標(唯讀)或 `:rw` 旗標(讀取/寫入)。例如,以下命令授予讀取/寫入權限。
$ docker run -v HOST-DIRECTORY:/CONTAINER-DIRECTORY:rw nginx
唯讀繫結掛載允許容器存取主機上已掛載的檔案以進行讀取,但不能更改或刪除檔案。使用讀取/寫入繫結掛載,容器可以修改或刪除已掛載的檔案,這些更改或刪除也會反映在主機系統上。唯讀繫結掛載可確保主機上的檔案不會被容器意外修改或刪除。
同步檔案共享
隨著程式碼庫規模的增長,傳統的檔案共享方法(如繫結掛載)可能會變得效率低下或速度緩慢,尤其是在需要頻繁存取檔案的開發環境中。 同步檔案共享利用同步檔案系統快取來提升繫結掛載效能。此最佳化可確保主機與虛擬機器 (VM) 之間的檔案存取快速且有效率。
試用看看
在本實作指南中,您將練習如何建立和使用繫結掛載,以在主機與容器之間共享檔案。
執行容器
下載並安裝 Docker Desktop。
使用 httpd 映像檔以下列命令啟動容器
$ docker run -d -p 8080:80 --name my_site httpd:2.4
這將在背景啟動 `httpd` 服務,並將網頁發佈到主機上的連接埠 `8080`。
開啟瀏覽器並存取 http://localhost:8080