在 VS Code 中试用

使用 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)),然后使用容器: 将 Docker Compose 文件添加到工作区命令来添加 Docker Compose 文件。按照提示操作。

您可以在添加 Dockerfile 的同时,通过打开命令面板⇧⌘P (Windows、Linux Ctrl+Shift+P))并使用容器: 将 Docker 文件添加到工作区命令来向工作区添加 Docker Compose 文件。系统将询问您是否要添加 Docker Compose 文件。如果您想保留现有的 Dockerfile,在提示覆盖 Dockerfile 时选择

容器工具扩展会将 docker-compose.yml 文件添加到您的工作区。此文件包含在生产环境中按预期启动容器的配置。在某些情况下,还会生成一个 docker-compose.debug.yml 文件。此文件提供了一种简化的启动模式,可用于启用调试器。

Screenshot of project with docker-compose files

VS Code 容器工具扩展生成的文件可以直接使用,但您也可以对其进行自定义以优化您的场景。然后,您可以使用容器: Compose Up 命令(右键单击 docker-compose.yml 文件,或在命令面板中查找该命令)一次性启动所有内容。您还可以从 VS Code 中的命令提示符或终端窗口使用 docker-compose up 命令来启动容器。请参阅 Docker Compose 文档,了解如何配置 Docker Compose 行为以及可用的命令行选项。

使用 docker-compose 文件,您现在可以在 docker-compose 文件中指定端口映射,而不是在 .json 配置文件中。有关示例,请参阅 Docker Compose 文档

提示: 使用 Docker Compose 时,不要指定主机端口。相反,让 Docker 自动选择一个随机可用端口,以避免端口冲突问题。

向项目添加新容器

如果您想添加另一个应用或服务,可以再次运行容器: 将 Docker Compose 文件添加到工作区命令,并选择覆盖现有的 docker-compose 文件,但这会丢失这些文件中的任何自定义设置。如果您想保留对 Compose 文件的更改,可以手动修改 docker-compose.yml 文件以添加新服务。通常,您可以复制现有服务部分,粘贴以创建新条目,并根据新服务适当更改名称。

您可以再次运行容器: 将 Docker 文件添加到工作区命令,为新应用生成 Dockerfile。虽然每个应用或服务都有自己的 Dockerfile,但每个工作区通常只有一个 docker-compose.yml 和一个 docker-compose.debug.yml 文件。

在 Python 项目中,Dockerfile.dockerignoredocker-compose*.yml 文件都位于工作区的根文件夹中。当您添加另一个应用或服务时,请将 Dockerfile 移动到应用的文件夹中。

在 Node.js 项目中,Dockerfile.dockerignore 文件将与该服务的 package.json 并置。

对于 .NET,当您创建 Docker Compose 文件时,文件夹结构已设置为处理多个项目,.dockerignoredocker-compose*.yml 放置在工作区根目录中(例如,如果项目在 src/project1 中,则文件在 src 中),因此当您添加另一个服务时,您将在一个文件夹(例如 project2)中创建另一个项目,并按照前面所述重新创建或修改 docker-compose 文件。

调试

首先,请参阅目标平台的调试文档,了解使用 VS Code 在容器中调试的基础知识。

如果您想在 Docker Compose 中进行调试,请按照上一节所述,使用两个 Docker Compose 文件中的一个运行命令容器: Compose Up,然后使用适当的附加启动配置进行附加。直接使用正常的启动配置启动不会使用 Docker Compose。

创建一个附加启动配置。这是 launch.json 中的一个部分。该过程主要是手动的,但在某些情况下,容器工具扩展可以通过添加一个预配置的启动配置来提供帮助,您可以将其用作模板并进行自定义。每个平台(Node.js、Python 和 .NET)的过程将在以下部分中描述。

Node.js

  1. 调试选项卡上,选择配置下拉菜单,选择新建配置,然后选择 Containers: Attach 配置模板容器: 附加到 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. 编辑完附加配置后,保存 launch.json,并将您的新启动配置选为活动配置。在调试选项卡中,在配置下拉菜单中找到新配置。

    Screenshot of Configuration dropdown

  5. 右键单击 docker-compose.debug.yml 文件,然后选择Compose Up

  6. 当您附加到暴露返回 HTML 的 HTTP 端点的服务时,Web 浏览器不会自动打开。要在浏览器中打开应用,请在侧边栏中选择容器,右键单击并选择在浏览器中打开。如果配置了多个端口,系统会要求您选择端口。

  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. 编辑完附加配置后,保存 launch.json。导航到调试选项卡,然后选择Python 调试器: 远程附加作为活动配置。

  4. 如果您已经有一个有效的 Dockerfile,我们建议运行命令容器: 将 Docker Compose 文件添加到工作区。这将创建一个 docker-compose.yml 文件,以及一个 docker-compose.debug.yml,后者会进行卷映射并在容器中启动 Python 调试器。如果您还没有 Dockerfile,我们建议运行容器: 将 Docker 文件添加到工作区并选择以包含 Docker Compose 文件。

    注意: 默认情况下,在使用容器: 将 Docker 文件添加到工作区时,选择 Django 和 Flask 选项将生成一个为 Gunicorn 配置的 Dockerfile。请按照容器中的 Python 快速入门中的说明进行操作,以确保在继续之前正确配置。

  5. 右键单击 docker-compose.debug.yml 文件(示例如下),然后选择Compose Up

    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 调试器: 远程附加启动配置的情况下按 F5 来附加调试器。

    Screenshot of debugging in Python

    注意: 如果您想将 Python 调试器导入到特定文件,更多信息可以在 debugpy README 中找到。

  7. 当您附加到暴露 HTTP 端点并返回 HTML 的服务时,Web 浏览器可能不会自动打开。要在浏览器中打开应用,请右键单击容器资源管理器中的容器,然后选择在浏览器中打开。如果配置了多个端口,系统会要求您选择端口。

    Screenshot - Open in Browser

    您现在正在容器中调试运行中的应用。

.NET

  1. 调试选项卡上,选择配置下拉菜单,选择新建配置,然后选择 Container Attach 配置模板容器: .NET 附加(预览)

  2. VS Code 尝试使用默认路径将 vsdbg 从主机复制到目标容器。您也可以在附加配置中提供现有 vsdbg 实例的路径。

     "netCore": {
         "debuggerPath": "/remote_debugger/vsdbg"
     }
    
  3. 编辑完附加配置后,保存 launch.json,并将您的新启动配置选为活动配置。在调试选项卡中,在配置下拉菜单中找到新配置。

  4. 右键单击 docker-compose.debug.yml 文件,然后选择Compose Up

  5. 当您附加到暴露返回 HTML 的 HTTP 端点的服务时,Web 浏览器不会自动打开。要在浏览器中打开应用,请在侧边栏中选择容器,右键单击并选择在浏览器中打开。如果配置了多个端口,系统会要求您选择端口。

  6. 以通常方式启动调试器。在调试选项卡中,选择绿色箭头(开始按钮)或使用 F5

    Screenshot of starting debugging

  7. 如果您尝试附加到在容器中运行的 .NET 应用,您将看到一个提示,要求您选择应用的容器。

    Screenshot of container selection

    要跳过此步骤,请在 launch.json 的附加配置中指定容器名称。

        "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 命令时,它会将这些文件合并为单个配置。默认情况下,容器: Compose Up 命令将单个文件作为输入传递给 Compose 命令,但您可以使用命令自定义来定制 compose up 命令以传递多个文件。或者,您可以使用自定义任务来调用带有所需参数的 docker-compose 命令。

注意: 如果您的工作区包含 docker-compose.ymldocker-compose.override.yml 且没有其他 Compose 文件,则 docker-compose 命令将在没有输入文件的情况下被调用,并隐式使用这些文件。在这种情况下,不需要自定义。

命令自定义

命令自定义提供了多种方法,可以根据您的要求自定义 compose up 命令。以下是 compose up 命令的一些示例命令自定义。

基础文件和覆盖文件

假设您的工作区有一个基础 Compose 文件(docker-compose.yml)和每个环境的覆盖文件(docker-compose.dev.ymldocker-compose.test.ymldocker-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"
  }
}

后续步骤