使用 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 文件。 该文件提供了一个简化的启动模式,以启用调试器。

VS Code Container Tools 扩展会生成可直接使用的文件,但您也可以根据自己的场景对其进行自定义以进行优化。 然后,您可以使用Containers: Compose Up命令(右键单击 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 文件,但您将丢失这些文件中的所有自定义设置。 如果要保留对 compose 文件的更改,可以手动修改 docker-compose.yml 文件以添加新服务。 通常,您可以复制现有的服务部分,将其粘贴以创建新条目,并根据需要更改新服务的名称。
您可以再次运行Containers: Add Docker Files to Workspace命令来为新应用生成 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)中创建一个新项目,然后重新创建或修改 compose 文件,如前所述。
调试
首先,请参阅目标平台的调试文档,以了解使用 VS Code 在容器中调试的基础知识
如果要使用 Docker Compose 进行调试,请运行Containers: Compose Up命令,使用前一部分中描述的两个 Docker Compose 文件之一,然后使用适当的Attach启动配置进行附加。 直接使用常规启动配置启动不会使用 Docker Compose。
创建一个Attach 启动配置。 这是 launch.json 中的一个部分。 该过程大部分是手动的,但在某些情况下,Container Tools 扩展可以通过添加可作为模板使用和自定义的预配置启动配置来提供帮助。 每个平台(Node.js、Python 和 .NET)的过程在以下部分中介绍。
Node.js
-
在Debug选项卡上,选择Configuration下拉菜单,选择New Configuration,然后选择
Containers: Attach配置模板Containers: Attach to 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 启动配置 - Attach 的示例
"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,并将新的启动配置选为活动配置。 在Debug选项卡中,从Configuration下拉菜单中找到新配置。
-
右键单击
docker-compose.debug.yml文件并选择Compose Up。 -
当您附加到暴露返回 HTML 的 HTTP 端点的服务时,Web 浏览器不会自动打开。 要在浏览器中打开应用程序,请在侧边栏中选择容器,右键单击并选择Open in Browser。 如果配置了多个端口,系统会要求您选择端口。
-
以通常的方式启动调试器。 从Debug选项卡中,选择绿色箭头(Start按钮)或使用 F5。
Python
要使用 Docker Compose 调试 Python,请遵循以下步骤
-
在Debug选项卡上,选择Configuration下拉菜单,选择New Configuration,选择Python Debugger,然后选择
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。 导航到Debug选项卡,并将Python Debugger: Remote Attach选为活动配置。 -
如果您已经有一个有效的 Dockerfile,我们建议运行Containers: Add Docker Compose Files to Workspace命令。 这将创建一个
docker-compose.yml文件以及一个docker-compose.debug.yml文件,后者将卷映射并启动容器中的 Python 调试器。 如果您还没有 Dockerfile,我们建议运行Containers: Add Docker Files to Workspace并选择Yes以包含 Docker Compose 文件。注意:默认情况下,当使用Containers: Add Docker Files to Workspace时,选择 Django 和 Flask 选项将为 Gunicorn 脚手架一个配置好的 Dockerfile。 请按照 在容器中快速启动 Python 应用程序 中的说明,确保其配置正确后再继续操作。
-
右键单击
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 -
构建并运行容器后,通过在选中Python Debugger: Remote Attach启动配置的情况下按 F5 来附加调试器。

注意:如果您想将 Python 调试器导入到特定文件中,可以在 debugpy README 中找到更多信息。
-
当您附加到暴露返回 HTML 的 HTTP 端点的服务时,Web 浏览器可能不会自动打开。 要在浏览器中打开应用程序,请在容器资源管理器中右键单击容器并选择Open in Browser。 如果配置了多个端口,系统会要求您选择端口。

您现在正在调试容器中运行的应用程序。
.NET
-
在Debug选项卡上,选择Configuration下拉菜单,选择New Configuration,然后选择
Container Attach配置模板Containers: .NET Attach (Preview)。 -
VS Code 尝试使用默认路径将
vsdbg从主机复制到目标容器。 您也可以在Attach配置中提供现有vsdbg实例的路径。"netCore": { "debuggerPath": "/remote_debugger/vsdbg" } -
编辑完Attach配置后,保存
launch.json,并将新的启动配置选为活动配置。 在Debug选项卡中,从Configuration下拉菜单中找到新配置。 -
右键单击
docker-compose.debug.yml文件并选择Compose Up。 -
当您附加到暴露返回 HTML 的 HTTP 端点的服务时,Web 浏览器不会自动打开。 要在浏览器中打开应用程序,请在侧边栏中选择容器,右键单击并选择Open in Browser。 如果配置了多个端口,系统会要求您选择端口。
-
以通常的方式启动调试器。 从Debug选项卡中,选择绿色箭头(Start按钮)或使用 F5。

-
如果您尝试附加到在容器中运行的 .NET 应用程序,系统会提示您选择应用程序的容器。

要跳过此步骤,请在 launch.json 的Attach配置中指定容器名称
"containerName": "Your ContainerName"接下来,系统会询问您是否要将调试器 (
vsdbg) 复制到容器中。 选择Yes。
如果所有内容都配置正确,调试器应已附加到您的 .NET 应用程序。

卷挂载
默认情况下,Container Tools 扩展不会对调试组件执行任何卷挂载。 对于 .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 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"
}
}