參加你附近的 ,瞭解 VS Code 中的 AI 輔助開發。

使用 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` 檔案。此檔案提供了一種簡化的啟動模式,可以啟用偵錯程式。

Screenshot of project with docker-compose files

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

  1. 除錯選項卡上,選擇配置下拉選單,選擇新建配置,然後選擇 `Containers: Attach` 配置模板 Containers: Attach to Node (容器:附加到 Node)。

  2. 在 `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
    
  3. 如果你有多個應用,你需要為其中一些應用更改埠,以確保每個應用都有一個唯一的埠。你可以在 `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.
         },
         // ...
     ]
    
  4. 編輯完附加 (Attach) 配置後,儲存 `launch.json`,並將你的新啟動配置選為活動配置。在除錯選項卡中,從配置下拉選單中找到新的配置。

    Screenshot of Configuration dropdown

  5. 右鍵單擊 `docker-compose.debug.yml` 檔案,然後選擇 Compose Up (Compose 啟動)。

  6. 當你附加到一個暴露了返回 HTML 的 HTTP 端點的服務時,Web 瀏覽器不會自動開啟。要用瀏覽器開啟應用,請在側邊欄中選擇該容器,右鍵單擊並選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。

  7. 以常規方式啟動偵錯程式。在除錯選項卡上,選擇綠色箭頭(啟動按鈕)或使用 F5

Python

要使用 Docker Compose 除錯 Python,請按照以下步驟操作

  1. 除錯選項卡上,選擇配置下拉選單,選擇新建配置,選擇Python 偵錯程式,然後選擇 `遠端附加 (Remote Attach)` 配置模板。

    Screenshot of Python Remote Attach

  2. 系統會提示你選擇要用於除錯的主機(例如,localhost)和埠。Python 的預設除錯埠是 5678。如果你有多個應用,你需要為其中一個應用更改埠,以確保每個應用都有一個唯一的埠。你可以在 `launch.json` 中指向正確的除錯埠,並儲存檔案。如果省略此項,埠將被自動選擇。

         "configurations": [
         {
            "name": "Python Debugger: Remote Attach",
            "type": "debugpy",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/app"
                }
            ]
        }
    
  3. 編輯完附加 (Attach) 配置後,儲存 `launch.json`。導航到除錯選項卡,並選擇 Python Debugger: Remote Attach (Python 偵錯程式:遠端附加)作為活動配置。

  4. 如果你已經有一個有效的 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 快速入門中的說明操作,以確保在繼續之前已正確配置。

  5. 右鍵單擊 `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
    
  6. 一旦你的容器構建並執行,透過在選擇了 Python Debugger: Remote Attach (Python 偵錯程式:遠端附加) 啟動配置的情況下按 F5 來附加偵錯程式。

    Screenshot of debugging in Python

    注意: 如果你想將 Python 偵錯程式匯入到特定檔案中,可以在 debugpy README 中找到更多資訊。

  7. 當你附加到一個暴露了 HTTP 端點並返回 HTML 的服務時,Web 瀏覽器可能不會自動開啟。要用瀏覽器開啟應用,請在容器資源管理器中右鍵單擊容器,然後選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。

    Screenshot - Open in Browser

    現在你正在除錯容器中執行的應用。

.NET

  1. 除錯選項卡上,選擇配置下拉選單,選擇新建配置,然後選擇 `容器附加 (Container Attach)` 配置模板 Containers: .NET Attach (Preview) (容器:.NET 附加 (預覽版))。

  2. VS Code 會嘗試使用預設路徑將 `vsdbg` 從主機複製到目標容器。你也可以在附加 (Attach) 配置中提供一個現有 `vsdbg` 例項的路徑。

     "netCore": {
         "debuggerPath": "/remote_debugger/vsdbg"
     }
    
  3. 編輯完附加 (Attach) 配置後,儲存 `launch.json`,並將你的新啟動配置選為活動配置。在除錯選項卡中,從配置下拉選單中找到新的配置。

  4. 右鍵單擊 `docker-compose.debug.yml` 檔案,然後選擇 Compose Up (Compose 啟動)。

  5. 當你附加到一個暴露了返回 HTML 的 HTTP 端點的服務時,Web 瀏覽器不會自動開啟。要用瀏覽器開啟應用,請在側邊欄中選擇該容器,右鍵單擊並選擇在瀏覽器中開啟 (Open in Browser)。如果配置了多個埠,系統會要求你選擇一個埠。

  6. 以常規方式啟動偵錯程式。在除錯選項卡上,選擇綠色箭頭(啟動按鈕)或使用 F5

    Screenshot of starting debugging

  7. 如果你嘗試附加到在容器中執行的 .NET 應用,系統會提示你選擇應用的容器。

    Screenshot of container selection

    要跳過此步驟,請在 launch.json 的附加 (Attach) 配置中指定容器名稱

        "containerName": "Your ContainerName"
    

    接下來,系統會詢問你是否要將偵錯程式 (`vsdbg`) 複製到容器中。選擇

    Screenshot of debugger prompt

如果一切配置正確,偵錯程式應該會附加到你的 .NET 應用。

Screenshot of debug session

卷掛載

預設情況下,容器工具擴充套件不會為除錯元件進行任何卷掛載。對於 .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"
  }
}

後續步驟