使用 Docker 撰写

Docker Compose 提供了一种编排多个容器一起工作的方法。示例包括处理请求和前端网站的服务,或使用 Redis 缓存等支持功能的服务。如果您使用微服务模型进行应用程序开发,则可以使用 Docker Compose 将应用程序代码分解为多个独立运行的服务,这些服务使用 Web 请求进行通信。本文帮助您为应用程序启用 Docker Compose,无论它们是 Node.js、Python 还是 .NET,还帮助您在 Visual Studio Code 中针对这些场景配置调试。

此外,对于单容器场景,使用 Docker Compose 提供了独立于工具的配置,而单个 Dockerfile 则无法提供这种配置。配置设置(例如容器的卷挂载、端口映射和环境变量)可以在 docker-compose YML 文件中声明。

要使用 Docker 扩展在 VS Code 中使用 Docker Compose,您应该已经熟悉Docker Compose的基础知识。

向您的项目添加 Docker Compose 支持

如果您已有一个或多个 Dockerfile,则可以通过打开命令面板( ⇧⌘P (Windows、Linux Ctrl+Shift+P ) ) 并使用Docker:将 Docker Compose 文件添加到工作区命令来添加 Docker Compose 文件。按照提示操作。

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

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

包含 docker-compose 文件的项目的屏幕截图

VS Code Docker 扩展生成开箱即用的文件,但您也可以自定义它们以针对您的场景进行优化。然后,您可以使用Docker Compose Up命令(右键单击该文件,或在命令面板docker-compose.yml中找到该命令)立即开始所有操作。您还可以使用VS Code 中的命令提示符或终端窗口中的命令来启动容器。请参阅Docker Compose 文档,了解如何配置 Docker Compose 行为以及可用的命令行选项。docker-compose up

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

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

将新容器添加到您的项目中

如果要添加其他应用程序或服务,可以再次运行“将 Docker Compose 文件添加到工作区”,并选择覆盖现有的 docker-compose 文件,但您将丢失这些文件中的任何自定义内容。如果要保留对撰写文件的更改,可以手动修改该docker-compose.yml文件以添加新服务。通常,您可以复制现有服务部分,将其粘贴以创建新条目,然后根据新服务的情况更改名称。

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

在 Python 项目中,Dockerfile.dockerignoredocker-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 文件之一运行命令Docker Compose Up ,然后使用适当的Attach启动配置进行附加。直接使用正常启动配置启动不使用 Docker Compose。

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

Node.js

  1. “调试”选项卡上,选择“配置”下拉列表,选择“新建配置”,然后选择Docker Attach配置模板Node.js Docker Attach (Preview)

  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": "Docker: Attach to Node",
             "remoteRoot": "/usr/src/app",
             "port": 9229 // Optional; otherwise inferred from the docker-compose.debug.yml.
         },
         // ...
     ]
    
  4. 完成编辑附加配置后,保存launch.json并选择新的启动配置作为活动配置。在“调试”选项卡中,在“配置”下拉列表中找到新配置。

    配置下拉列表的屏幕截图

  5. 右键单击该docker-compose.debug.yml文件并选择“撰写”

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

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

Python

要使用 Docker Compose 调试 Python,请按照以下步骤操作:

  1. “调试”选项卡上,选择“配置”下拉列表,选择“新建配置”,选择“Python ”,然后选择Remote Attach配置模板。

    Python 远程连接的屏幕截图

  2. 系统会提示您选择要用于调试的主机(例如 localhost)和端口。Python 的默认调试端口是 5678。如果您有多个应用程序,则需要更改其中一个应用程序的端口,以便每个应用程序都有唯一的端口。您可以在 中指向正确的调试端口launch.json,然后保存文件。如果省略此项,将自动选择端口。

         "configurations": [
         {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "port": 5678,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}",
                    "remoteRoot": "/app"
                }
            ]
        }
    
  3. 编辑完附加配置后,保存launch.json. 导航到“调试”选项卡并选择“Python:远程连接”作为活动配置。

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

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

  5. 右键单击该docker-compose.debug.yml文件(示例如下所示)并选择“撰写”

    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: Remote Attach启动配置按F5来附加调试器。

    Python 调试截图

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

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

    屏幕截图 - 在浏览器中打开

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

。网

  1. “调试”选项卡上,选择“配置”下拉列表,选择“新建配置”,然后选择Docker Attach配置模板.NET Core Docker Attach (Preview)

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

     "netCore": {
         "debuggerPath": "/remote_debugger/vsdbg"
     }
    
  3. 完成编辑附加配置后,保存launch.json并选择新的启动配置作为活动配置。在“调试”选项卡中,在“配置”下拉列表中找到新配置。

  4. 右键单击该docker-compose.debug.yml文件并选择“撰写”

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

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

    开始调试截图

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

    容器选择截图

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

        "containerName": "Your ContainerName"
    

    接下来,系统会询问您是否要将调试器 ( vsdbg) 复制到容器中。选择

    调试器提示符的屏幕截图

如果一切配置正确,调试器应附加到您的 .NET 应用程序。

调试会话的屏幕截图

卷安装

默认情况下,Docker 扩展不会为调试组件进行任何卷安装。在 .NET 或 Node.js 中不需要它,因为所需的组件已内置到运行时中。如果您的应用程序需要卷安装,请使用文件volumes中的标签指定它们docker-compose*.yml

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

Docker Compose 包含多个 Compose 文件

工作区可以有多个 docker-compose 文件来处理不同的环境,例如开发、测试和生产。配置的内容可以分成多个文件。例如,定义所有环境的公共信息的基本撰写文件和定义特定于环境的信息的单独的覆盖文件。当这些文件作为命令的输入传递时docker-compose,它会将这些文件组合成一个配置。默认情况下,Docker: Compose Up命令将单个文件作为输入传递给 compose 命令,但您可以使用命令自compose up定义来自定义该命令以传递多个文件。或者,您可以使用自定义任务来调用具有所需参数的命令。docker-compose

注意:如果您的工作区有docker-compose.yml并且docker-compose.override.yml没有其他撰写文件,则docker-compose在没有输入文件的情况下调用该命令,并且它会隐式使用这些文件。在这种情况下,不需要定制。

命令定制

命令定制compose up提供了多种方式来根据您的需求定制命令。以下是该compose up命令的一些示例命令定制。

基本文件和覆盖文件

假设您的工作区有一个基本撰写文件 ( 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并使用相应的模板。

"docker.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例如:

"docker.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"
  }
}

下一步