使用綁定掛載 (Bind mounts)

第 4 部分中,您使用了儲存卷掛載 (volume mount) 來保存資料庫中的資料。當您需要一個持久性的位置來儲存應用程式資料時,儲存卷掛載是一個絕佳的選擇。

綁定掛載是另一種掛載方式,它允許您將主機檔案系統中的目錄共享到容器中。在開發應用程式時,您可以使用綁定掛載將原始程式碼掛載到容器內。只要您儲存檔案,容器就會立即看到程式碼的變更。這意味著您可以在容器內執行監控檔案系統變更的處理程序,並對這些變更做出回應。

在本章中,您將了解如何使用綁定掛載和名為 nodemon 的工具來監控檔案變更,並自動重新啟動應用程式。大多數其他程式語言和框架中也有類似的工具。

快速比較儲存卷類型

以下是使用 --mount 進行具名儲存卷和綁定掛載的範例:

  • 具名儲存卷:type=volume,src=my-volume,target=/usr/local/data
  • 綁定掛載:type=bind,src=/path/to/data,target=/usr/local/data

下表概述了儲存卷掛載和綁定掛載之間的主要差異。

具名儲存卷繫結掛載
主機位置由 Docker 選擇由您決定
將容器內容填充到新儲存卷中
支援儲存卷驅動程式

嘗試使用綁定掛載

在了解如何使用綁定掛載進行應用程式開發之前,您可以執行一個簡單的實驗,以對綁定掛載的運作方式有實務上的理解。

  1. 請確認您的 getting-started-app 目錄位於 Docker Desktop 檔案共享設定所定義的目錄內。此設定定義了您可以與容器共享檔案系統的哪些部分。有關存取此設定的詳細資訊,請參閱檔案共享

    注意

    檔案共享 (File sharing) 分頁僅在 Hyper-V 模式下可用,因為在 WSL 2 模式和 Windows 容器模式下,檔案會自動進行共享。

  2. 開啟終端機並切換目錄至 getting-started-app

  3. 執行下列指令,在 ubuntu 容器中以綁定掛載的方式啟動 bash

    $ docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
    
    $ docker run -it --mount "type=bind,src=%cd%,target=/src" ubuntu bash
    
    $ docker run -it --mount type=bind,src="/$(pwd)",target=/src ubuntu bash
    
    $ docker run -it --mount "type=bind,src=$($pwd),target=/src" ubuntu bash
    

    --mount type=bind 選項告訴 Docker 建立一個綁定掛載,其中 src 是主機機器上的當前工作目錄 (getting-started-app),而 target 是該目錄在容器內應顯示的位置 (/src)。

  4. 執行指令後,Docker 會在容器檔案系統的根目錄中啟動一個互動式 bash 工作階段。

    root@ac1237fad8db:/# pwd
    /
    root@ac1237fad8db:/# ls
    bin   dev  home  media  opt   root  sbin  srv  tmp  var
    boot  etc  lib   mnt    proc  run   src   sys  usr
    
  5. 切換目錄至 src 目錄。

    這正是您啟動容器時掛載的目錄。列出此目錄的內容,將會顯示與主機機器 getting-started-app 目錄中相同的檔案。

    root@ac1237fad8db:/# cd src
    root@ac1237fad8db:/src# ls
    Dockerfile  node_modules  package.json  spec  src  yarn.lock
    
  6. 建立一個名為 myfile.txt 的新檔案。

    root@ac1237fad8db:/src# touch myfile.txt
    root@ac1237fad8db:/src# ls
    Dockerfile  myfile.txt  node_modules  package.json  spec  src  yarn.lock
    
  7. 在主機上開啟 getting-started-app 目錄,觀察 myfile.txt 是否存在於該目錄中。

    ├── getting-started-app/
    │ ├── Dockerfile
    │ ├── myfile.txt
    │ ├── node_modules/
    │ ├── package.json
    │ ├── spec/
    │ ├── src/
    │ └── yarn.lock
  8. 從主機上刪除 myfile.txt 檔案。

  9. 在容器中再次列出 app 目錄的內容。請觀察該檔案現在已經消失了。

    root@ac1237fad8db:/src# ls
    Dockerfile  node_modules  package.json  spec  src  yarn.lock
    
  10. 使用 Ctrl + D 停止互動式容器工作階段。

以上就是對綁定掛載的簡短介紹。此程序展示了檔案如何在主機與容器之間共享,以及變更如何即時反映在雙方。現在,您可以使用綁定掛載來進行軟體開發。

開發容器

使用綁定掛載在本地開發環境中非常普遍。其優勢在於開發機器不需要安裝所有的建置工具和環境。只需一個 docker run 指令,Docker 就會拉取相依套件和工具。

在開發容器中執行您的應用程式

以下步驟說明如何執行一個帶有綁定掛載的開發容器,它會執行以下操作:

  • 將您的原始程式碼掛載到容器中
  • 安裝所有相依套件
  • 啟動 nodemon 以監控檔案系統變更

您可以使用 CLI 或 Docker Desktop 來執行帶有綁定掛載的容器。

  1. 確保目前沒有任何 getting-started 容器在執行。

  2. getting-started-app 目錄中執行下列指令。

    $ docker run -dp 127.0.0.1:3000:3000 \
        -w /app --mount type=bind,src="$(pwd)",target=/app \
        node:18-alpine \
        sh -c "yarn install && yarn run dev"
    

    以下是該指令的分解說明:

    • -dp 127.0.0.1:3000:3000 - 與之前相同。在分離 (背景) 模式下執行並建立連接埠對映。
    • -w /app - 設定「工作目錄」,即指令執行時所在的當前目錄。
    • --mount type=bind,src="$(pwd)",target=/app - 將主機的當前目錄綁定掛載到容器內的 /app 目錄。
    • node:18-alpine - 要使用的映像檔。請注意,這是您應用程式 Dockerfile 中的基礎映像檔。
    • sh -c "yarn install && yarn run dev" - 要執行的指令。您正在使用 sh 啟動一個 shell (alpine 沒有 bash),執行 yarn install 來安裝套件,然後執行 yarn run dev 來啟動開發伺服器。如果您查看 package.json,會發現 dev 指令碼會啟動 nodemon
  3. 您可以使用 docker logs <container-id> 來觀察日誌。當您看到以下內容時,表示準備就緒:

    $ docker logs -f <container-id>
    nodemon -L src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    觀察完日誌後,按下 Ctrl+C 退出。

  1. 確保目前沒有任何 getting-started 容器在執行。

  2. getting-started-app 目錄中執行下列指令。

    $ docker run -dp 127.0.0.1:3000:3000 `
        -w /app --mount "type=bind,src=$pwd,target=/app" `
        node:18-alpine `
        sh -c "yarn install && yarn run dev"

    以下是該指令的分解說明:

    • -dp 127.0.0.1:3000:3000 - 與之前相同。在分離 (背景) 模式下執行並建立連接埠對映。
    • -w /app - 設定「工作目錄」,即指令執行時所在的當前目錄。
    • --mount "type=bind,src=$pwd,target=/app" - 將主機的當前目錄綁定掛載到容器內的 /app 目錄。
    • node:18-alpine - 要使用的映像檔。請注意,這是您應用程式 Dockerfile 中的基礎映像檔。
    • sh -c "yarn install && yarn run dev" - 要執行的指令。您正在使用 sh 啟動一個 shell (alpine 沒有 bash),執行 yarn install 來安裝套件,然後執行 yarn run dev 來啟動開發伺服器。如果您查看 package.json,會發現 dev 指令碼會啟動 nodemon
  3. 您可以使用 docker logs <container-id> 來觀察日誌。當您看到以下內容時,表示準備就緒:

    $ docker logs -f <container-id>
    nodemon -L src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    觀察完日誌後,按下 Ctrl+C 退出。

  1. 確保目前沒有任何 getting-started 容器在執行。

  2. getting-started-app 目錄中執行下列指令。

    $ docker run -dp 127.0.0.1:3000:3000 ^
        -w /app --mount "type=bind,src=%cd%,target=/app" ^
        node:18-alpine ^
        sh -c "yarn install && yarn run dev"
    

    以下是該指令的分解說明:

    • -dp 127.0.0.1:3000:3000 - 與之前相同。在分離 (背景) 模式下執行並建立連接埠對映。
    • -w /app - 設定「工作目錄」,即指令執行時所在的當前目錄。
    • --mount "type=bind,src=%cd%,target=/app" - 將主機的當前目錄綁定掛載到容器內的 /app 目錄。
    • node:18-alpine - 要使用的映像檔。請注意,這是您應用程式 Dockerfile 中的基礎映像檔。
    • sh -c "yarn install && yarn run dev" - 要執行的指令。您正在使用 sh 啟動一個 shell (alpine 沒有 bash),執行 yarn install 來安裝套件,然後執行 yarn run dev 來啟動開發伺服器。如果您查看 package.json,會發現 dev 指令碼會啟動 nodemon
  3. 您可以使用 docker logs <container-id> 來觀察日誌。當您看到以下內容時,表示準備就緒:

    $ docker logs -f <container-id>
    nodemon -L src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    觀察完日誌後,按下 Ctrl+C 退出。

  1. 確保目前沒有任何 getting-started 容器在執行。

  2. getting-started-app 目錄中執行下列指令。

    $ docker run -dp 127.0.0.1:3000:3000 \
        -w //app --mount type=bind,src="/$(pwd)",target=/app \
        node:18-alpine \
        sh -c "yarn install && yarn run dev"
    

    以下是該指令的分解說明:

    • -dp 127.0.0.1:3000:3000 - 與之前相同。在分離 (背景) 模式下執行並建立連接埠對映。
    • -w //app - 設定「工作目錄」,即指令執行時所在的當前目錄。
    • --mount type=bind,src="/$(pwd)",target=/app - 將主機的當前目錄綁定掛載到容器內的 /app 目錄。
    • node:18-alpine - 要使用的映像檔。請注意,這是您應用程式 Dockerfile 中的基礎映像檔。
    • sh -c "yarn install && yarn run dev" - 要執行的指令。您正在使用 sh 啟動一個 shell (alpine 沒有 bash),執行 yarn install 來安裝套件,然後執行 yarn run dev 來啟動開發伺服器。如果您查看 package.json,會發現 dev 指令碼會啟動 nodemon
  3. 您可以使用 docker logs <container-id> 來觀察日誌。當您看到以下內容時,表示準備就緒:

    $ docker logs -f <container-id>
    nodemon -L src/index.js
    [nodemon] 2.0.20
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching path(s): *.*
    [nodemon] watching extensions: js,mjs,json
    [nodemon] starting `node src/index.js`
    Using sqlite database at /etc/todos/todo.db
    Listening on port 3000
    

    觀察完日誌後,按下 Ctrl+C 退出。

確保目前沒有任何 getting-started 容器在執行。

使用綁定掛載執行映像檔。

  1. 選擇 Docker Desktop 頂部的搜尋框。

  2. 在搜尋視窗中,選擇 Images 分頁。

  3. 在搜尋框中,指定容器名稱 getting-started

    提示

    使用搜尋篩選器來篩選映像檔,僅顯示 Local images

  4. 選擇您的映像檔,然後選擇 Run

  5. 選擇 Optional settings

  6. Host path 中,指定主機機器上 getting-started-app 目錄的路徑。

  7. Container path 中,指定 /app

  8. 選擇 Run

您可以使用 Docker Desktop 觀察容器日誌。

  1. 在 Docker Desktop 中選擇 Containers
  2. 選擇您的容器名稱。

當您看到以下內容時,表示準備就緒:

nodemon -L src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

使用開發容器進行應用程式開發

更新主機機器上的應用程式,並觀察容器中反映的變更。

  1. src/static/js/app.js 檔案中,將第 109 行的「Add Item」按鈕改為「Add」。

    - {submitting ? 'Adding...' : 'Add Item'}
    + {submitting ? 'Adding...' : 'Add'}
    

    儲存檔案。

  2. 在網頁瀏覽器中重新整理頁面,由於綁定掛載的存在,您應該會幾乎立即看到變更。Nodemon 會偵測到變更並重新啟動伺服器。Node 伺服器重新啟動可能需要幾秒鐘。如果出現錯誤,請在幾秒鐘後再試一次。

    Screenshot of updated label for Add button
  3. 您可以隨意進行任何您想做的其他變更。每次變更並儲存檔案時,由於綁定掛載,變更都會反映在容器中。當 Nodemon 偵測到變更時,它會自動重新啟動容器內的應用程式。完成後,請停止容器並使用以下指令建置您的新映像檔:

    $ docker build -t getting-started .
    

總結

此時,您可以在不重新建置映像檔的情況下,持久儲存資料庫並在開發過程中查看應用程式的變更。

除了儲存卷掛載和綁定掛載之外,Docker 還支援其他掛載類型和儲存驅動程式,以處理更複雜和專門的使用場景。

相關資訊

下一步

為了讓您的應用程式準備好投入生產環境,您需要將資料庫從 SQLite 遷移到更具擴展性的方案。為了簡單起見,您將繼續使用關聯式資料庫,並將應用程式切換為使用 MySQL。但是,該如何執行 MySQL?如何讓容器相互通訊?您將在下一節中學習這些內容。

多容器應用程式
© . This site is unofficial and not affiliated with Kubernetes or Docker Inc.