使用 Docker Compose
Docker Compose 提供了一種編排多個協同工作的容器的方法。例如,一個處理請求的服務和一個前端網站,或者一個使用 Redis 快取等支援功能的服務。如果你的應用開發使用微服務模型,你可以使用 Docker Compose 將應用程式碼分解為多個獨立執行的服務,這些服務之間透過 Web 請求進行通訊。本文幫助你為你的應用(無論是 Node.js、Python 還是 .NET)啟用 Docker Compose,並幫助你在 Visual Studio Code 中為這些場景配置除錯。
此外,對於單容器場景,使用 Docker Compose 提供了一種獨立於工具的配置方式,這是單個 Dockerfile 無法做到的。諸如容器的卷掛載、埠對映和環境變數等配置設定都可以在 docker-compose YML 檔案中宣告。
要在 VS Code 中使用容器工具擴充套件來使用 Docker Compose,你應該已經熟悉 Docker Compose 的基礎知識。
向你的專案新增 Docker Compose 支援
如果你已經有一個或多個 Dockerfile,可以透過開啟命令面板 (⇧⌘P (Windows、Linux 為 Ctrl+Shift+P)) 並使用 Containers: Add Docker Compose Files to Workspace (容器:向工作區新增 Docker Compose 檔案) 命令來新增 Docker Compose 檔案。按照提示操作即可。
你可以在新增 Dockerfile 的同時向工作區新增 Docker Compose 檔案,方法是開啟命令面板 (⇧⌘P (Windows、Linux 為 Ctrl+Shift+P)) 並使用 Containers: Add Docker Files to Workspace (容器:向工作區新增 Docker 檔案) 命令。系統會詢問你是否要新增 Docker Compose 檔案。如果你想保留現有的 Dockerfile,在提示是否覆蓋 Dockerfile 時選擇否。
容器工具擴充套件會將 `docker-compose.yml` 檔案新增到你的工作區。此檔案包含在生產環境中按預期啟動容器的配置。在某些情況下,還會生成一個 `docker-compose.debug.yml` 檔案。此檔案提供了一種簡化的啟動模式,可以啟用偵錯程式。
VS Code 容器工具擴充套件生成的檔案可以開箱即用,但你也可以自定義它們以最佳化你的場景。然後,你可以使用 Containers: Compose Up (容器:Compose 啟動) 命令(右鍵單擊 `docker-compose.yml` 檔案,或在命令面板中找到該命令)來一次性啟動所有服務。你也可以在 VS Code 的命令提示符或終端視窗中使用 `docker-compose up` 命令來啟動容器。請參閱 Docker Compose 文件,瞭解如何配置 Docker Compose 的行為以及有哪些可用的命令列選項。
有了 docker-compose 檔案,你現在可以在 docker-compose 檔案中指定埠對映,而不是在 .json 配置檔案中。有關示例,請參閱 Docker Compose 文件。
提示:使用 Docker Compose 時,不要指定主機埠。相反,讓 Docker 隨機選擇一個可用的埠,以自動避免埠衝突問題。
向你的專案新增新容器
如果你想新增另一個應用或服務,可以再次執行 Containers: Add Docker Compose Files to Workspace (容器:向工作區新增 Docker Compose 檔案),並選擇覆蓋現有的 docker-compose 檔案,但你將丟失這些檔案中的任何自定義設定。如果你想保留對 compose 檔案的更改,可以手動修改 `docker-compose.yml` 檔案來新增新服務。通常,你可以複製現有的服務部分,貼上以建立一個新條目,並根據新服務更改名稱。
你可以再次執行 Containers: Add Docker Files to Workspace (容器:向工作區新增 Docker 檔案) 命令來為新應用生成 `Dockerfile`。雖然每個應用或服務都有自己的 Dockerfile,但每個工作區通常只有一個 `docker-compose.yml` 和一個 `docker-compose.debug.yml` 檔案。
在 Python 專案中,`Dockerfile`、`.dockerignore`、`docker-compose*.yml` 檔案都位於工作區的根資料夾中。當你新增另一個應用或服務時,請將 Dockerfile 移動到該應用的資料夾中。
在 Node.js 專案中,`Dockerfile` 和 `.dockerignore` 檔案將與該服務的 `package.json` 檔案位於同一目錄下。
對於 .NET,建立 Docker Compose 檔案時,資料夾結構已經設定為處理多個專案,`.dockerignore` 和 `docker-compose*.yml` 檔案放置在工作區根目錄中(例如,如果專案在 `src/project1` 中,那麼這些檔案就在 `src` 目錄中),所以當你新增另一個服務時,你會在另一個資料夾(比如 `project2`)中建立另一個專案,然後如前所述重新建立或修改 docker-compose 檔案。
除錯
首先,請參考你的目標平臺的除錯文件,以瞭解在 VS Code 中進行容器除錯的基礎知識
如果你想在 Docker Compose 中進行除錯,請使用前面部分描述的兩個 Docker Compose 檔案之一執行 Containers: Compose Up (容器:Compose 啟動) 命令,然後使用相應的附加 (Attach) 啟動配置進行附加。直接使用常規啟動配置啟動不會使用 Docker Compose。
建立一個附加 (Attach) 啟動配置。這是 `launch.json` 中的一個部分。這個過程大多是手動的,但在某些情況下,容器工具擴充套件可以透過新增一個預配置的啟動配置來提供幫助,你可以將其用作模板並進行自定義。下面將分別描述每個平臺(Node.js、Python 和 .NET)的過程。
Node.js
-
在除錯選項卡上,選擇配置下拉選單,選擇新建配置,然後選擇 `Containers: Attach` 配置模板 Containers: Attach to Node (容器:附加到 Node)。
-
在 `docker-compose.debug.yml` 檔案中配置除錯埠。這個埠在建立檔案時已經設定好,所以你可能不需要更改它。在下面的示例中,埠 9229 同時用於主機和容器的除錯。
version: '3.4' services: node-hello: image: node-hello build: . environment: NODE_ENV: development ports: - 3000 - 9229:9229 command: node --inspect=0.0.0.0:9229 ./bin/www
-
如果你有多個應用,你需要為其中一些應用更改埠,以確保每個應用都有一個唯一的埠。你可以在 `launch.json` 中指向正確的除錯埠,並儲存檔案。如果省略此項,埠將被自動選擇。
下面是一個顯示 Node.js 啟動配置 - 附加的示例
"configurations": [ { "type": "node", "request": "attach", "name": "Containers: Attach to Node", "remoteRoot": "/usr/src/app", "port": 9229 // Optional; otherwise inferred from the docker-compose.debug.yml. }, // ... ]
-
編輯完附加 (Attach) 配置後,儲存 `launch.json`,並將你的新啟動配置選為活動配置。在除錯選項卡中,從配置下拉選單中找到新的配置。
-
右鍵單擊 `docker-compose.debug.yml` 檔案,然後選擇 Compose Up (Compose 啟動)。
-
當你附加到一個暴露了返回 HTML 的 HTTP 端點的服務時,Web 瀏覽器不會自動開啟。要用瀏覽器開啟應用,請在側邊欄中選擇該容器,右鍵單擊並選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。
-
以常規方式啟動偵錯程式。在除錯選項卡上,選擇綠色箭頭(啟動按鈕)或使用 F5。
Python
要使用 Docker Compose 除錯 Python,請按照以下步驟操作
-
在除錯選項卡上,選擇配置下拉選單,選擇新建配置,選擇Python 偵錯程式,然後選擇 `遠端附加 (Remote Attach)` 配置模板。
-
系統會提示你選擇要用於除錯的主機(例如,localhost)和埠。Python 的預設除錯埠是 5678。如果你有多個應用,你需要為其中一個應用更改埠,以確保每個應用都有一個唯一的埠。你可以在 `launch.json` 中指向正確的除錯埠,並儲存檔案。如果省略此項,埠將被自動選擇。
"configurations": [ { "name": "Python Debugger: Remote Attach", "type": "debugpy", "request": "attach", "port": 5678, "host": "localhost", "pathMappings": [ { "localRoot": "${workspaceFolder}", "remoteRoot": "/app" } ] }
-
編輯完附加 (Attach) 配置後,儲存 `launch.json`。導航到除錯選項卡,並選擇 Python Debugger: Remote Attach (Python 偵錯程式:遠端附加)作為活動配置。
-
如果你已經有一個有效的 Dockerfile,我們建議執行 Containers: Add Docker Compose Files to Workspace (容器:向工作區新增 Docker Compose 檔案) 命令。這將建立一個 `docker-compose.yml` 檔案和一個 `docker-compose.debug.yml` 檔案,後者會進行卷對映並在容器中啟動 Python 偵錯程式。如果你還沒有 Dockerfile,我們建議執行 Containers: Add Docker Files to Workspace (容器:向工作區新增 Docker 檔案) 並選擇是以包含 Docker Compose 檔案。
注意:預設情況下,使用 Containers: Add Docker Files to Workspace (容器:向工作區新增 Docker 檔案) 時,選擇 Django 和 Flask 選項會生成一個為 Gunicorn 配置的 Dockerfile。請按照容器中的 Python 快速入門中的說明操作,以確保在繼續之前已正確配置。
-
右鍵單擊 `docker-compose.debug.yml` 檔案(示例如下)並選擇 Compose Up (Compose 啟動)。
version: '3.4' services: pythonsamplevscodedjangotutorial: image: pythonsamplevscodedjangotutorial build: context: . dockerfile: ./Dockerfile command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 manage.py runserver 0.0.0.0:8000 --nothreading --noreload"] ports: - 8000:8000 - 5678:5678
-
一旦你的容器構建並執行,透過在選擇了 Python Debugger: Remote Attach (Python 偵錯程式:遠端附加) 啟動配置的情況下按 F5 來附加偵錯程式。
注意: 如果你想將 Python 偵錯程式匯入到特定檔案中,可以在 debugpy README 中找到更多資訊。
-
當你附加到一個暴露了 HTTP 端點並返回 HTML 的服務時,Web 瀏覽器可能不會自動開啟。要用瀏覽器開啟應用,請在容器資源管理器中右鍵單擊容器,然後選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。
現在你正在除錯容器中執行的應用。
.NET
-
在除錯選項卡上,選擇配置下拉選單,選擇新建配置,然後選擇 `容器附加 (Container Attach)` 配置模板 Containers: .NET Attach (Preview) (容器:.NET 附加 (預覽版))。
-
VS Code 會嘗試使用預設路徑將 `vsdbg` 從主機複製到目標容器。你也可以在附加 (Attach) 配置中提供一個現有 `vsdbg` 例項的路徑。
"netCore": { "debuggerPath": "/remote_debugger/vsdbg" }
-
編輯完附加 (Attach) 配置後,儲存 `launch.json`,並將你的新啟動配置選為活動配置。在除錯選項卡中,從配置下拉選單中找到新的配置。
-
右鍵單擊 `docker-compose.debug.yml` 檔案,然後選擇 Compose Up (Compose 啟動)。
-
當你附加到一個暴露了返回 HTML 的 HTTP 端點的服務時,Web 瀏覽器不會自動開啟。要用瀏覽器開啟應用,請在側邊欄中選擇該容器,右鍵單擊並選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。
-
以常規方式啟動偵錯程式。在除錯選項卡上,選擇綠色箭頭(啟動按鈕)或使用 F5。
-
如果你嘗試附加到在容器中執行的 .NET 應用,系統會提示你選擇應用的容器。
要跳過此步驟,請在 launch.json 的附加 (Attach) 配置中指定容器名稱
"containerName": "Your ContainerName"
接下來,系統會詢問你是否要將偵錯程式 (`vsdbg`) 複製到容器中。選擇是。
如果一切配置正確,偵錯程式應該會附加到你的 .NET 應用。
卷掛載
預設情況下,容器工具擴充套件不會為除錯元件進行任何卷掛載。對於 .NET 或 Node.js 來說,這是不必要的,因為所需的元件已經內建在執行時中。如果你的應用需要卷掛載,請在 `docker-compose*.yml` 檔案中使用 `volumes` 標籤來指定它們。
volumes:
- /host-folder-path:/container-folder-path
使用多個 Compose 檔案的 Docker Compose
工作區可以有多個 docker-compose 檔案來處理不同的環境,如開發、測試和生產。配置內容可以拆分到多個檔案中。例如,一個定義所有環境通用資訊的基礎 compose 檔案,以及多個定義特定環境資訊的獨立覆蓋檔案。當這些檔案作為輸入傳遞給 `docker-compose` 命令時,它會將這些檔案合併成一個單一的配置。預設情況下,Containers: Compose Up (容器:Compose 啟動) 命令只傳遞一個檔案作為 compose 命令的輸入,但你可以使用命令自定義功能來自定義 `compose up` 命令以傳遞多個檔案。或者,你可以使用自定義任務來呼叫帶有所需引數的 `docker-compose` 命令。
注意:如果你的工作區有 `docker-compose.yml` 和 `docker-compose.override.yml` 檔案,並且沒有其他 compose 檔案,那麼 `docker-compose` 命令將在沒有輸入檔案的情況下被呼叫,它會隱式使用這兩個檔案。在這種情況下,不需要進行自定義。
命令自定義
命令自定義提供了多種方式來根據你的需求自定義 `compose up` 命令。以下是 `compose up` 命令的一些示例自定義。
基礎檔案和覆蓋檔案
假設你的工作區有一個基礎 compose 檔案 (`docker-compose.yml`) 和每個環境的覆蓋檔案 (`docker-compose.dev.yml`、`docker-compose.test.yml` 和 `docker-compose.prod.yml`),並且你總是使用基礎檔案和一個覆蓋檔案來執行 `docker compose up`。在這種情況下,`compose up` 命令可以如下例所示進行自定義。當呼叫 `compose up` 命令時,`${configurationFile}` 會被所選檔案替換。
"docker.commands.composeUp": [
{
"label": "override",
"template": "docker-compose -f docker-compose.yml ${configurationFile} up -d --build",
}
]
模板匹配
假設你為每個環境都有一組不同的輸入檔案。你可以定義多個帶有正則表示式匹配的模板,所選檔名將與此 `match` 屬性進行匹配,並使用相應的模板。
"containers.commands.composeUp": [
{
"label": "dev-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.dev.yml up -d --build",
"match": "dev"
},
{
"label": "test-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.debug.yml -f docker-compose.test.yml up -d --build",
"match": "test"
},
{
"label": "prod-match",
"template": "docker-compose -f docker-compose.yml -f docker-compose.release.yml -f docker-compose.prod.yml up -d --build",
"match": "prod"
}
]
在呼叫命令時選擇一個模板
如果你從命令模板中省略 `match` 屬性,那麼每次呼叫 `compose up` 命令時,系統都會詢問你使用哪個模板。例如
"containers.commands.composeUp": [
{
"label": "dev",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.dev.yml ${configurationFile} up -d --build"
},
{
"label": "test",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.test.yml ${configurationFile} up -d --build"
},
{
"label": "prod",
"template": "docker-compose -f docker-compose.yml -f docker-compose.common.prod.yml ${configurationFile} up -d --build"
},
],
自定義任務
除了使用命令自定義,你還可以定義一個如下所示的任務來呼叫 `docker-compose` 命令。有關此選項的更多詳細資訊,請參閱自定義任務。
{
"type": "shell",
"label": "compose-up-dev",
"command": "docker-compose -f docker-compose.yml -f docker-compose.Common.yml -f docker-compose.dev.yml up -d --build",
"presentation": {
"reveal": "always",
"panel": "new"
}
}