使用繫結掛載
在第 4 部分中,您使用了卷掛載來持久化資料庫中的資料。當您需要一個持久的地方來儲存應用程式資料時,卷掛載是一個很好的選擇。
繫結掛載是另一種型別的掛載,它允許您將主機檔案系統中的目錄共享到容器中。在開發應用程式時,您可以使用繫結掛載將原始碼掛載到容器中。容器會立即看到您對程式碼所做的更改,只要您儲存檔案。這意味著您可以在容器中執行監視檔案系統更改並對其做出響應的程序。
在本章中,您將看到如何使用繫結掛載和一個名為 nodemon 的工具來監視檔案更改,然後自動重啟應用程式。在大多數其他語言和框架中都有類似的工具。
卷型別快速比較
以下是使用 --mount
的命名卷和繫結掛載的示例
- 命名卷:
type=volume,src=my-volume,target=/usr/local/data
- 繫結掛載:
type=bind,src=/path/to/data,target=/usr/local/data
下表概述了卷掛載和繫結掛載之間的主要區別。
命名卷 | 繫結掛載 | |
---|---|---|
主機位置 | 由 Docker 選擇 | 由您決定 |
用容器內容填充新卷 | 是 | 否 |
支援卷驅動 | 是 | 否 |
嘗試繫結掛載
在瞭解如何使用繫結掛載來開發應用程式之前,您可以進行一個快速實驗,以實際瞭解繫結掛載的工作原理。
請確認您的
getting-started-app
目錄位於 Docker Desktop 檔案共享設定中定義的目錄中。此設定定義了您可以與容器共享檔案系統的哪些部分。有關訪問該設定的詳細資訊,請參閱檔案共享。注意檔案共享選項卡僅在 Hyper-V 模式下可用,因為檔案在 WSL 2 模式和 Windows 容器模式下是自動共享的。
開啟一個終端,並將目錄更改為
getting-started-app
目錄。執行以下命令,在一個帶有繫結掛載的
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
)。執行該命令後,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
將目錄更改為
src
目錄。這是您在啟動容器時掛載的目錄。列出此目錄的內容將顯示與您主機上
getting-started-app
目錄中相同的檔案。root@ac1237fad8db:/# cd src root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
建立一個名為
myfile.txt
的新檔案。root@ac1237fad8db:/src# touch myfile.txt root@ac1237fad8db:/src# ls Dockerfile myfile.txt node_modules package.json spec src yarn.lock
在主機上開啟
getting-started-app
目錄,並觀察到myfile.txt
檔案在該目錄中。├── getting-started-app/ │ ├── Dockerfile │ ├── myfile.txt │ ├── node_modules/ │ ├── package.json │ ├── spec/ │ ├── src/ │ └── yarn.lock
從主機刪除
myfile.txt
檔案。在容器中,再次列出
app
目錄的內容。觀察到檔案現在已經不見了。root@ac1237fad8db:/src# ls Dockerfile node_modules package.json spec src yarn.lock
使用
Ctrl
+D
停止互動式容器會話。
這就是對繫結掛載的簡要介紹。此過程演示了檔案如何在主機和容器之間共享,以及更改如何立即在兩側反映出來。現在您可以使用繫結掛載來開發軟體了。
開發容器
使用繫結掛載是本地開發設定的常見做法。其優點在於開發機器不需要安裝所有的構建工具和環境。只需一條 docker run 命令,Docker 就會拉取依賴項和工具。
在開發容器中執行您的應用程式
以下步驟描述瞭如何使用繫結掛載執行一個開發容器,該容器會執行以下操作:
- 將您的原始碼掛載到容器中
- 安裝所有依賴項
- 啟動
nodemon
來監視檔案系統的變化
您可以使用 CLI 或 Docker Desktop 來執行帶有繫結掛載的容器。
請確保當前沒有正在執行的
getting-started
容器。在
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
。
您可以使用
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
容器。在
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
。
您可以使用
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
容器。在
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
。
您可以使用
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
容器。在
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
。
您可以使用
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
容器。
使用繫結掛載執行映象。
選擇 Docker Desktop 頂部的搜尋框。
在搜尋視窗中,選擇 Images 選項卡。
在搜尋框中,指定容器名稱,
getting-started
。提示使用搜索過濾器來篩選映象,並僅顯示本地映象。
選擇您的映象,然後選擇執行。
選擇可選設定。
在主機路徑中,指定您主機上
getting-started-app
目錄的路徑。在容器路徑中,指定
/app
。選擇執行。
您可以使用 Docker Desktop 檢視容器日誌。
- 在 Docker Desktop 中選擇 Containers。
- 選擇您的容器名稱。
當您看到以下內容時,就表示準備就緒了:
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
使用開發容器開發您的應用程式
在您的主機上更新您的應用,並檢視更改在容器中的反映。
在
src/static/js/app.js
檔案的第 109 行,將 "Add Item" 按鈕的文字更改為 "Add"。- {submitting ? 'Adding...' : 'Add Item'} + {submitting ? 'Adding...' : 'Add'}
儲存檔案。
重新整理您的網頁瀏覽器,您應該會因為繫結掛載而幾乎立即看到更改的反映。Nodemon 會檢測到更改並重啟伺服器。Node 伺服器可能需要幾秒鐘才能重啟。如果您遇到錯誤,請在幾秒鐘後嘗試重新整理。
您可以隨意進行任何其他您想做的更改。每次您進行更改並儲存檔案時,由於繫結掛載,更改都會在容器中反映出來。當 Nodemon 檢測到更改時,它會自動在容器內重啟應用。完成後,停止容器並使用以下命令構建您的新映象:
$ docker build -t getting-started .
摘要
此時,您可以在開發過程中持久化您的資料庫並檢視應用程式的更改,而無需重新構建映象。
除了卷掛載和繫結掛載,Docker 還支援其他掛載型別和儲存驅動程式,以處理更復雜和專門的用例。
相關資訊
後續步驟
為了準備您的應用進行生產部署,您需要將資料庫從 SQLite 遷移到能夠更好擴充套件的資料庫。為簡單起見,您將繼續使用關係型資料庫,並將您的應用切換為使用 MySQL。但是,您應該如何執行 MySQL?如何讓容器之間相互通訊?您將在下一節中學到這些內容。
多容器應用