使用 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 中通过 Container Tools 扩展使用 Docker Compose,您应该已经熟悉 Docker Compose 的基础知识。

为项目添加 Docker Compose 支持

如果您已经拥有一个或多个 Dockerfile,可以通过打开命令面板⇧⌘P(Windows, Linux Ctrl+Shift+P),并使用 Containers: Add Docker Compose Files to Workspace 命令来添加 Docker Compose 文件。请按照提示操作。

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

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

Screenshot of project with docker-compose files

VS Code Container Tools 扩展生成的开箱即用文件,您也可以根据自身场景进行自定义以实现优化。然后,您可以使用 Containers: Compose Up 命令(右键点击 docker-compose.yml 文件,或在命令面板中查找该命令)一次性启动所有服务。您也可以在 VS Code 的命令提示符或终端窗口中使用 docker-compose up 命令来启动容器。有关如何配置 Docker Compose 行为及可用命令行选项的详细信息,请参考 Docker Compose 文档

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

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

向项目中添加新容器

如果您想添加另一个应用或服务,可以再次运行 Containers: Add Docker Compose Files to Workspace,并选择覆盖现有的 docker-compose 文件;但请注意,这会导致这些文件中的自定义内容丢失。如果您想保留对 compose 文件的更改,可以手动修改 docker-compose.yml 文件以添加新服务。通常,您可以复制现有的服务部分,粘贴以创建新条目,并根据新服务相应地更改名称。

您可以再次运行 Containers: Add Docker Files to Workspace 命令,为新应用生成 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 文件之一运行 Containers: Compose Up 命令,然后使用适当的 Attach(附加)启动配置进行附加。直接使用普通启动配置进行启动不会使用 Docker Compose。

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

Node.js

  1. 调试选项卡上,选择配置下拉菜单,选择添加配置...,然后选择 Containers: Attach 配置模板 Containers: Attach to 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

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

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

Python

对于使用 Docker Compose 进行 Python 调试,请遵循以下步骤:

  1. 调试选项卡上,选择配置下拉菜单,选择添加配置...,选择 Python Debugger,并选择 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 选为活动配置。

  4. 如果您已经有一个有效的 Dockerfile,建议运行 Containers: Add Docker Compose Files to Workspace 命令。这将创建一个 docker-compose.yml 文件以及一个 docker-compose.debug.yml 文件,后者会对 Python 调试器进行卷映射并在容器中启动它。如果您还没有 Dockerfile,建议运行 Containers: Add Docker Files to Workspace 并选择以包含 Docker Compose 文件。

    注意:默认情况下,使用 Containers: Add Docker Files to Workspace 时,选择 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 Debugger: Remote Attach 启动配置的情况下点击 F5 来附加调试器。

    Screenshot of debugging in Python

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

  7. 当您附加到一个公开 HTTP 端点并返回 HTML 的服务时,Web 浏览器可能不会自动打开。要在浏览器中打开应用,请右键点击 Container Explorer 中的容器,并选择 Open in Browser。如果配置了多个端口,系统会要求您选择端口。

    Screenshot - Open in Browser

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

.NET

  1. 调试选项卡上,选择配置下拉菜单,选择添加配置...,并选择 Container Attach 配置模板 Containers: .NET Attach (Preview)

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

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

  4. 右键点击 docker-compose.debug.yml 文件并选择 Compose Up

  5. 当您附加到一个公开 HTTP 端点并返回 HTML 的服务时,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

卷挂载 (Volume mounts)

默认情况下,Container Tools 扩展不会为调试组件执行任何卷挂载。在 .NET 或 Node.js 中不需要这样做,因为所需的组件已内置于运行时中。如果您的应用需要卷挂载,请通过使用 docker-compose*.yml 文件中的 volumes 标签来指定。

volumes:
    - /host-folder-path:/container-folder-path

多 Docker Compose 文件配置

工作区可以包含多个 docker-compose 文件,以处理开发、测试和生产等不同环境。配置内容可以拆分到多个文件中。例如,一个定义所有环境通用信息的基础 compose 文件,以及定义特定环境信息的单独覆盖文件。当这些文件作为输入传递给 docker-compose 命令时,它会将这些文件合并为一个配置。默认情况下,Containers: 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.yml, docker-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"
  }
}

后续步骤

© . This site is unofficial and not affiliated with Microsoft.