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

容器中的 Python

在本教程中,您将学习如何

  • 创建一个 Dockerfile 文件,描述一个简单的 Python 容器。
  • 构建、运行和验证一个 DjangoFlask 或通用 Python 应用的功能。
  • 调试在容器中运行的应用。

先决条件

创建 Python 项目

如果您还没有 Python 项目,请按照 Python 入门 教程进行操作。

注意:如果您想将完整的 Django 或 Flask Web 应用容器化,您可以从以下示例之一开始

注意:在本教程中,请务必使用示例存储库的 tutorial 分支。

验证您的应用正常运行后,您现在可以将您的应用程序容器化。

将 Docker 文件添加到项目

  1. 在 VS Code 中打开项目文件夹。

  2. 打开命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)),然后选择 Docker: 将 Docker 文件添加到工作区...

    Add Dockerfile to a Python project

  3. 系统提示您选择应用类型时,请选择 Python: DjangoPython: FlaskPython: 通用 作为应用类型。在本教程中,我们将重点介绍 Python: 通用 的情况,但也将包括 Django 和 Flask 的说明。

  4. 输入应用入口点的相对路径。这排除了您开始使用的工作区文件夹。如果您按照 Python 入门 教程创建了一个名为 hello.py 的 Python 应用,请选中它。

    Django:选择 manage.py(根文件夹)或 subfolder_name/manage.py。请参阅 官方 Django 文档

    Flask:选择创建 Flask 实例的位置的路径。请参阅 官方 Flask 文档

    提示:您也可以输入文件夹名称的路径,只要此文件夹包含一个 __main__.py 文件。

  5. 选择端口号。我们建议选择 1024 或更高的端口以减轻 以 root 用户身份运行 的安全问题。任何未使用的端口都可以,但 Django 和 Flask 使用标准的默认端口。

    Django:默认端口 8000。

    Flask:默认端口是 5000。

  6. 系统提示您是否要包含 Docker Compose 时,如果您不想要 Docker Compose 文件,请选择 。如果您选择 ,则需要在 Dockerfile 中验证 wsgi.py 文件的路径,以便成功运行 Compose Up 命令。Compose 通常用于同时运行多个容器。

  7. 有了所有这些信息,Docker 扩展将创建以下文件

    • 一个 Dockerfile。要详细了解此文件中的 IntelliSense,请参阅 概述

    • 一个 .dockerignore 文件,通过排除不需要的文件和文件夹(例如 .git.vscode__pycache__)来减小镜像大小。

    • 如果您使用的是 Docker Compose,则将创建一个 docker-compose.ymldocker-compose.debug.yml 文件。

    • 如果不存在,则会创建一个 requirements.txt 文件来捕获所有应用依赖项。

    重要提示:要使用我们的设置,Python 框架(Django/Flask)和 Gunicorn 必须包含在 requirements.txt 文件中。如果虚拟环境/主机计算机已经安装了这些先决条件,并且应该与容器环境相同,请通过在终端中运行 pip freeze > requirements.txt 来确保将应用依赖项移植过来。这将覆盖您当前的 requirements.txt 文件。

(可选)向镜像添加环境变量

此步骤不是必需的,但它包含在内,旨在帮助您了解如何添加需要在容器环境中设置的环境变量。

Docker 扩展通过使用 IntelliSense 提供自动补全和上下文帮助来帮助您编写 Dockerfile。要查看此功能的实际操作

  1. 打开 Dockerfile

  2. EXPOSE 语句下方,键入 ⌃Space (Windows、Linux Ctrl+Space) 以触发 IntelliSense,然后滚动到 ENV

    Adding environment variable to Dockerfile

  3. TabEnter 键完成语句,然后将 key 设置为变量的名称,并将 value 设置为其值。

有关在 Dockerfile 中设置和使用环境变量的更多信息,请参阅 Docker 文档中的 ENV 指令以及 环境替换 部分。

Django 和 Flask 应用的 Gunicorn 修改

为了给 Python Web 开发人员提供一个良好的起点,我们选择使用 Gunicorn 作为默认的 Web 服务器。由于它在默认的 Dockerfile 中被引用,因此它被包含在 requirements.txt 文件中作为依赖项。如果在 requirements.txt 中没有看到它,请运行 pip install gunicorn,然后运行 pip freeze > requirements.txt 重新生成 requirements.txt 文件。

  • Django:要使用 Gunicorn,它必须绑定到一个应用程序可调用对象(应用程序服务器用于与你的代码通信的入口点)。此可调用对象在 Django 应用程序的 wsgi.py 文件中声明。为了实现这种绑定,Dockerfile 中的最后一行是

    CMD ["gunicorn", "--bind", "0.0.0.0:8000", "{workspace_folder_name}.wsgi"]
    

    如果你的项目不遵循 Django 的默认项目结构(即,一个工作区文件夹和一个 wsgi.py 文件 >位于与工作区同名的子文件夹中),则必须覆盖 Dockerfile 中的 Gunicorn 入口点以找到正确的 wsgi.py 文件。

    如果你的 wsgi.py 文件位于根文件夹中,则上面命令中的最后一个参数将为 "wsgi"。在子文件夹中,该参数将为 "subfolder1_name.subfolder2_name.wsgi"

  • Flask:要使用 Gunicorn,它必须绑定到一个应用程序可调用对象(应用程序服务器用于与你的代码通信的入口点)。此可调用对象对应于你创建的 Flask 实例的 **文件位置** 和 **变量名称**。根据 官方 Flask 文档,用户通常以这种方式在主模块或包的 __init__.py 文件中创建 Flask 实例

    from flask import Flask
    app = Flask(__name__) # Flask instance named app
    

    为了实现这种绑定,Dockerfile 中的最后一行是

    CMD ["gunicorn", "--bind", "0.0.0.0:5000", "{subfolder}.{module_file}:app"]
    

    在 **Docker: 将 Docker 文件添加到工作区...** 命令期间,你将配置 Flask 实例的路径,但是 Docker 扩展假定你的 Flask 实例变量名为 app。如果不是这种情况,则必须在 Dockerfile 中更改变量名称。

    如果你的主模块位于根文件夹中,并且名为 main.py,并且具有名为 myapp 的 Flask 实例变量,则上面命令中的最后一个参数将为 "main:myapp"。在子文件夹中,该参数将为 "subfolder1_name.subfolder2_name.main:myapp"

构建、运行和调试容器

**Docker: 将 Docker 文件添加到工作区...** 命令会自动创建 Docker 启动配置,以在调试模式下构建和运行你的容器。要调试你的 Python 应用程序容器

  1. 导航到包含你的应用程序启动代码的文件,并设置一个断点。

  2. 导航到 **运行和调试** 并选择 **Docker: Python - 常规**、**Docker: Python - Django** 或 **Docker: Python - Flask**,具体取决于情况。

    Selected Docker debug configuration

  3. 使用 F5 键开始调试。

    • Docker 镜像正在构建。
    • Docker 容器正在运行。
    • Python 调试器在断点处停止。
  4. 单步执行此行。

  5. 准备就绪后,按继续。

Docker 扩展会将你的浏览器启动到随机映射的端口

Django website launches

提示:要修改 Docker 构建设置(例如更改镜像标签),请导航到 .vscode -> tasks.json,在 dockerBuild 属性下的 docker-build 任务中。使用 IntelliSense(⌃Space(Windows、Linux Ctrl+Space)显示所有其他有效指令。

使用 Docker Explorer

Docker 资源管理器提供交互式体验,用于检查和管理 Docker 资产,例如容器、镜像等。要查看示例

  1. 导航到 Docker 资源管理器。

  2. 在 **容器** 选项卡中,右键单击你的容器,然后选择 **查看日志**。

    Viewing the logs of a container

  3. 输出将显示在终端中。

在 Azure 中构建镜像

你可以使用命令 **Azure 容器注册表:在 Azure 中构建镜像** 来构建镜像,然后可以将其部署到 Azure 应用服务或 Azure 容器应用。

  1. 安装 Azure 资源扩展。打开 **命令面板** (⇧⌘P(Windows、Linux Ctrl+Shift+P),然后搜索命令 **Azure: 登录**。如果你没有 Azure 帐户,可以注册 免费试用

  2. 有两种方法可以调用在 Azure 中构建命令。你可以右键单击 Dockerfile,然后选择 **在 Azure 中构建镜像**。你也可以使用 **命令面板** (⇧⌘P(Windows、Linux Ctrl+Shift+P),然后搜索命令 **Azure 容器注册表:在 Azure 中构建镜像**。

    Invoke the command Build Image in Azure

  3. 为构建的镜像选择名称和标签。你将在容器注册表中使用它来识别它。

    Choose the name and tag for the built image.

  4. 选择要使用的 Azure 订阅。

  5. 选择现有的 Azure 容器注册表,或创建一个新的注册表。当你创建一个新的注册表时,系统会要求你提供名称、资源组、位置以及定价选项,例如基本版、标准版或高级版。你可以在 定价 - 容器注册表 中了解这些选项的成本。

  6. 指定基本操作系统,Linux 或 Windows。此选择必须与 Dockerfile 保持一致。

    Choose the base OS for the built image

构建镜像的过程可能需要几分钟。你可以在终端中跟踪进度。如果你遇到错误(Error: failed to download context.),请尝试在容器注册表上使用 **刷新** 选项,然后请求另一个构建。在重新构建之前,手动删除旧的镜像。

部署到 Azure App Service 或 Azure 容器应用

容器镜像构建完成后,它应该出现在容器注册表中,并带有你指定的标签。现在已经构建完成,你可以将其部署到 Azure 应用服务或 Azure 容器应用。建议使用 Azure 应用服务 扩展进行 Azure 应用服务的部署,并需要使用 Azure 容器应用 扩展进行 Azure 容器应用的部署。如果你安装了 Azure 工具扩展包,则可以获得两者,其中包含用于各种 Azure 开发场景的一组工具。

  1. 右键单击镜像标签,然后选择 **将镜像部署到 Azure 应用服务** 或 **将镜像部署到 Azure 容器应用**。

    Deploy image to Azure App Service

  2. 提供网站的名称。它必须是唯一的名称,对于 Django 应用程序,它还必须在 settings.py 文件的 ALLOWED_HOSTS 列表中列为有效的主机名。

  3. 提供资源组、位置和应用服务计划。如果你刚刚开始使用,可以选择免费计划。

  4. 镜像已部署;该过程可能需要几分钟。部署完成后,将显示一个包含按钮的通知,你可以使用该按钮访问该网站。你也可以使用该网站的地址 {appname}.azurewebsites.net,其中 {appname} 是你在创建它时提供的名称。如果它一开始无法正常工作,请在几分钟后重试。第一次尝试超时或返回错误的情况并不少见。这只是意味着应用服务尚未准备好接收请求。

  5. 在应用程序代码中进行一个小的更改,使它在某个页面上可见,然后保存该文件。

  6. 使用 Azure 图标打开 **资源** 视图,并展开你的订阅的节点,以找到你在上一步中部署的应用服务。

  7. 右键单击应用服务节点,查看可用选项。选择 **部署到 Web 应用**,然后指定要部署的应用程序文件夹。

    Deploy to Web App

    当你收到有关这将覆盖之前的部署的警告时,选择 **部署** 以确认。

    这可能需要几分钟;你可以在终端窗口中监控进度。完成时,将提供一个包含访问网站的按钮。

    Browse website button

    使用该按钮并验证你的更改是否反映在网站上。

恭喜你,你已使用 VS Code 中的 Python 创建并部署了一个托管在云中并在互联网上可用的网站!

释放资源

Azure 门户 中,删除资源组以释放你在本练习中创建的所有资源。

后续步骤

完成了!现在你的容器已准备就绪,你可能想要