现已推出!阅读 10 月份的新功能和修复。

在容器内调试 Python

在将 Docker 文件添加到 Python 项目时,会添加任务和启动配置以在 Docker 容器内调试应用程序。为了适应 Python 项目的各种场景,某些应用程序可能需要额外的配置。

配置 Docker 容器入口点

您可以通过在 tasks.json 中设置属性来配置 Docker 容器的入口点。当您首次使用 Docker: 将 Docker 文件添加到工作区... 命令时,VS Code 会自动配置容器入口点。

示例:为 Python 模块配置入口点

{
  "tasks": [
    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": ["docker-build"],
      "python": {
        "module": "myapp"
      }
    }
  ]
}

示例:为 Python 文件配置入口点

{
  "tasks": [
    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": ["docker-build"],
      "python": {
        "args": ["runserver", "0.0.0.0:8000", "--nothreading", "--noreload"],
        "file": "manage.py"
      }
    }
  ]
}

自动将浏览器启动到应用程序的入口页面

您可以选择 Docker: Python - DjangoDocker: Python - Flask 启动配置,以自动将浏览器启动到应用程序的主页。此功能默认启用,但您可以通过在 launch.json 中设置 dockerServerReadyAction 对象来显式配置此行为。

此功能取决于应用程序的几个方面

  • 应用程序**必须输出到调试控制台或 Docker 日志**。
  • 应用程序必须记录“服务器已准备就绪”消息。
  • 应用程序必须提供一个可浏览的页面。

以下是如何使用 dockerServerReadyAction 来启动浏览器,根据特定服务器消息模式打开 about.html 页面

{
  "configurations": [
    {
      "name": "Docker: Python - Django",
      "type": "docker",
      "request": "launch",
      "preLaunchTask": "docker-run: debug",
      "python": {
        "pathMappings": [
          {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/app"
          }
        ],
        "projectType": "django"
      },
      "dockerServerReadyAction": {
        "action": "openExternally",
        "pattern": "Starting development server at (https?://\\S+|[0-9]+)",
        "uriFormat": "%s://127.0.0.1:%s/about.html"
      }
    }
  ]
}

**注意**:在 pattern 属性中找到的正则表达式只是尝试捕获类似于“在 https://127.0.0.1:8000 上启动开发服务器”的日志消息。它适应 http 或 https 的 url、任何主机名和任何端口的变化。

重要的 dockerServerReadyAction 对象属性

  • action:找到模式时要采取的操作。可以是 debugWithChromeopenExternally

  • pattern:如果应用程序记录的消息与上面显示的不一样,请将 dockerServerReadyAction 对象的 pattern 属性设置为与该消息匹配的 JavaScript 正则表达式。正则表达式应包含一个捕获组,对应于应用程序正在监听的端口。

  • uriFormat:默认情况下,Docker 扩展会打开浏览器的主页(无论该页面如何确定)。如果您希望浏览器打开特定页面(如上面的示例),则 dockerServerReadyAction 对象的 uriFormat 属性应设置为包含两个字符串标记的格式字符串,以指示协议和端口替换。

如何在 Django 或 Flask 应用程序中启用热重载

当您选择 Docker: 将 Docker 文件添加到工作区 用于 Django 或 Flask 时,我们会为您提供一个为静态部署配置的 Dockerfile 和 tasks.json。每次对应用程序代码进行更改时,您都需要重新构建和重新运行容器。热重载允许您在容器继续运行时可视化应用程序代码中的更改。按照以下步骤启用热重载

对于 Django 应用程序

  1. 在 Dockerfile 中,注释掉将应用程序代码添加到容器的代码行。

    #ADD . /app
    
  2. tasks.json 文件中的 docker-run 任务中,创建一个新的 dockerRun 属性,其中包含 volumes 属性。此设置创建从当前工作区文件夹(应用程序代码)到容器中 /app 文件夹的映射。

    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": [
        "docker-build"
      ],
      "dockerRun": {
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      ...
    }
    
  3. 通过**删除** --noreload--nothreading 来编辑 python 属性。

    {
      ...
      "dockerRun": {
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      "python": {
        "args": [
          "runserver",
          "0.0.0.0:8000",
        ],
        "file": "manage.py"
      }
    }
    
  4. 选择 Docker: Python – Django 启动配置,然后按 F5 构建并运行容器。

  5. 修改并保存任何文件。

  6. 刷新浏览器并验证更改是否已生效。

对于 Flask 应用程序

  1. 在 Dockerfile 中,注释掉将应用程序代码添加到容器的代码行。

    #ADD . /app
    
  2. tasks.json 文件中的 docker-run 任务中,通过在 env 属性中添加 FLASK_ENV 以及 volumes 属性来编辑现有的 dockerRun 属性。此设置创建从当前工作区文件夹(应用程序代码)到容器中 /app 文件夹的映射。

    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": [
        "docker-build"
      ],
      "dockerRun": {
        "env": {
          "FLASK_APP": "path_to/flask_entry_point.py",
          "FLASK_ENV": "development"
        },
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      ...
    }
    
  3. 通过**删除** --no-reload--no-debugger 来编辑 python 属性。

    {
      ...
      "dockerRun": {
        "env": {
          "FLASK_APP": "path_to/flask_entry_point.py",
          "FLASK_ENV": "development"
        },
        "volumes": [
          {
            "containerPath": "/app", "localPath": "${workspaceFolder}"
          }
        ]
      },
      "python": {
        "args": [
          "run",
          "--host", "0.0.0.0",
          "--port", "5000"
        ],
        "module": "flask"
      }
    }
    
  4. 选择 Docker: Python – Flask 启动配置,然后按 F5 构建并运行容器。

  5. 修改并保存任何文件。

  6. 刷新浏览器并验证更改是否已生效。

如何一起构建和运行容器

  1. 在前面提到的 tasks.json 文件中,存在对 docker-build 任务的依赖关系。该任务是 tasks.jsontasks 数组的一部分。例如
"tasks":
[
  {
    ...
  },
  {
    "label": "docker-build",
    "type": "docker-build",
    "dockerBuild": {
        "context": "${workspaceFolder}",
        "dockerfile": "${workspaceFolder}/Dockerfile",
        "tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
    }
  }
]

提示:正如依赖关系明确地指出 docker-build 作为其依赖关系,该名称必须与该任务匹配。您可以根据需要更改名称。

  1. JSON 中的 dockerBuild 对象允许使用以下参数

    • context:Docker 构建上下文,从该上下文调用您的 Dockerfile
    • dockerfile:要执行的 Dockerfile 的路径
    • tag:要构建的镜像的名称,包含其版本标签
  2. 总的来说,VS Code 的构建和调试 Flask 应用程序的设置可以是

    • launch.json

      {
        "version": "0.2.0",
        "configurations": [
          {
            "name": "Debug Flask App",
            "type": "docker",
            "request": "launch",
      
            "preLaunchTask": "docker-run: debug",
            "python": {
              "pathMappings": [
                {
                  "localRoot": "${workspaceFolder}",
                  "remoteRoot": "/app"
                }
              ],
              "projectType": "flask"
            },
            "dockerServerReadyAction": {
              "action": "openExternally",
              "pattern": "Running on (http?://\\S+|[0-9]+)",
              "uriFormat": "%s://127.0.0.1:%s/"
            }
          }
        ]
      }
      
    • tasks.json

      {
        "version": "2.0.0",
        "tasks": [
          {
            "type": "docker-run",
            "label": "docker-run: debug",
            "dependsOn": ["docker-build"],
            "dockerRun": {
              "containerName": "YOUR_IMAGE_NAME",
              "image": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG",
              "env": {
                "FLASK_APP": "path_to/flask_entry_point.py",
                "FLASK_ENV": "development"
              },
              "volumes": [
                {
                  "containerPath": "/app",
                  "localPath": "${workspaceFolder}"
                }
              ],
              "ports": [
                {
                  "containerPort": 5000,
                  "hostPort": 5000
                }
              ]
            },
            "python": {
              "args": ["run", "--host", "0.0.0.0", "--port", "5000"],
              "module": "flask"
            }
          },
          {
            "label": "docker-build",
            "type": "docker-build",
            "dockerBuild": {
              "context": "${workspaceFolder}",
              "dockerfile": "${workspaceFolder}/Dockerfile",
              "tag": "YOUR_IMAGE_NAME:YOUR_IMAGE_TAG"
            }
          }
        ]
      }
      

下一步

了解更多关于