與容器共享本機檔案

說明

每個容器都具備其運作所需的一切,無需依賴主機上任何預先安裝的相依性。由於容器在隔離環境中執行,因此它們對主機和其他容器的影響極小。這種隔離性帶來了一個主要優點:容器可將與主機系統和其他容器的衝突降至最低。然而,這種隔離性也意味著容器預設情況下無法直接存取主機上的資料。

想像一下,您有一個 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) 之間的檔案存取快速且有效率。

試用看看

在本實作指南中,您將練習如何建立和使用繫結掛載,以在主機與容器之間共享檔案。

執行容器

  1. 下載並安裝 Docker Desktop。

  2. 使用 httpd 映像檔以下列命令啟動容器

    $ docker run -d -p 8080:80 --name my_site httpd:2.4
    

    這將在背景啟動 `httpd` 服務,並將網頁發佈到主機上的連接埠 `8080`。

  3. 開啟瀏覽器並存取 http://localhost:8080

使用繫結掛載

使用繫結掛載,您可以將主機電腦上的設定檔映射到容器內的特定位置。在本範例中,您將瞭解如何使用繫結掛載來更改網頁的外觀和風格。

  1. 使用 Docker Desktop 儀表板刪除現有的容器。

    A screenshot of Docker Desktop Dashboard showing how to delete the httpd container
  2. 在您的主機系統上建立一個名為 `public_html` 的新目錄。

    $ mkdir public_html
    
  3. 將目錄更改為 `public_html` 並建立一個名為 `index.html` 的檔案,其中包含以下內容。這是一個基本的 HTML 文件,它建立了一個簡單的網頁,以友善的鯨魚歡迎您。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title> My Website with a Whale & Docker!</title>
    </head>
    <body>
    <h1>Whalecome!!</h1>
    <p>Look! There's a friendly whale greeting you!</p>
    <pre id="docker-art">
       ##         .
      ## ## ##        ==
     ## ## ## ## ##    ===
     /"""""""""""""""""\___/ ===
    {                       /  ===-
    \______ O           __/
    \    \         __/
     \____\_______/
    
    Hello from Docker!
    </pre>
    </body>
    </html>
  4. 現在可以執行容器了。`--mount` 和 `-v` 範例會產生相同的結果。除非您在執行第一個範例後移除 `my_site` 容器,否則您無法同時執行它們。


    $ docker run -d --name my_site -p 8080:80 -v .:/usr/local/apache2/htdocs/ httpd:2.4
    
    $ docker run -d --name my_site -p 8080:80 --mount type=bind,source=./,target=/usr/local/apache2/htdocs/ httpd:2.4
    

    **提示**

    在 Windows PowerShell 中使用 `-v` 或 `--mount` 旗標時,您需要提供目錄的絕對路徑,而不能只使用 `./`。這是因為 PowerShell 處理相對路徑的方式與 bash(常用於 Mac 和 Linux 環境)不同。

    現在所有東西都已啟動並運行,您應該能夠透過 http://localhost:8080 存取網站,並找到一個以友善鯨魚歡迎您的新網頁。

在 Docker Desktop 儀表板上存取檔案

  1. 您可以透過選擇容器的「檔案」索引標籤,然後選擇 /usr/local/apache2/htdocs/ 目錄中的檔案,來檢視容器內已掛載的檔案。然後,選擇「開啟檔案編輯器」。

    A screenshot of Docker Desktop Dashboard showing the mounted files inside the a container
  2. 刪除主機上的檔案,並確認容器中的檔案也被刪除。您會發現 Docker Desktop Dashboard 的「檔案」底下不再存在這些檔案。

    A screenshot of Docker Desktop Dashboard showing the deleted files inside the a container
  3. 在主機系統上重新建立 HTML 檔案,並查看該檔案是否重新出現在 Docker Desktop Dashboard 的「容器」底下「檔案」索引標籤中。現在,您也可以存取該網站了。

停止您的容器

容器會持續運行,直到您將其停止。

  1. 前往 Docker Desktop Dashboard 中的「容器」檢視。

  2. 找到您想要停止的容器。

  3. 在「動作」欄中選擇「刪除」動作。

A screenshot of Docker Desktop Dashboard showing how to delete the container

其他資源

以下資源將幫助您進一步了解繫結掛載

後續步驟

現在您已經了解如何與容器共用本機檔案,接下來該學習多容器應用程式了。