使用繫結掛載

第 5 部分 中,您使用了一個卷掛載來持久化資料庫中的資料。當您需要一個持久的位置來儲存您的應用程式資料時,卷掛載是一個不錯的選擇。

繫結掛載是另一種型別的掛載,它允許您將主機檔案系統中的目錄共享到容器中。在處理應用程式時,您可以使用繫結掛載將原始碼掛載到容器中。容器會立即看到您對程式碼所做的更改,只要您儲存了檔案。這意味著您可以在容器中執行觀察檔案系統更改並響應它們的程序。

在本章中,您將瞭解如何使用繫結掛載和一個名為 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 檔案共享設定中定義的目錄中。此設定定義了您可以與容器共享的檔案系統哪些部分。有關訪問設定的詳細資訊,請參閱 MacWindowsLinux 的主題。

  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
    

    --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. 在搜尋視窗中,選擇映象選項卡。

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

    提示

    使用搜索過濾器過濾映象,只顯示本地映象

  4. 選擇您的映象,然後選擇執行

  5. 選擇可選設定

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

  7. 容器路徑中,指定 /app

  8. 選擇執行

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

  1. 在 Docker Desktop 中選擇容器
  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 行,將“新增專案”按鈕更改為僅顯示“新增”。

    - {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?您如何允許容器相互通訊?您將在下一節中瞭解這些內容。