使用 Azure 容器应用和 PostgreSQL 生成和部署 Python Web 应用

本文是有关如何将 Python Web 应用容器化和部署到 Azure 容器应用的教程的一部分。 借助容器应用,无需管理复杂的基础结构,即可部署容器化应用。

本教程的这一部分介绍如何容器化和部署 Python 示例 Web 应用(Django 或 Flask)。 具体而言,在云中生成容器映像并将其部署到 Azure 容器应用。 定义环境变量,使容器应用能够连接到 Azure Database for PostgreSQL 灵活服务器 实例,其中示例应用存储数据。

此服务关系图突出显示了本文中介绍的组件:生成和部署容器映像。

A screenshot of the services in the Tutorial - Deploy a Python App on Azure Container Apps. Section highlighted is what is covered in this article.

获取示例应用

分叉并将示例代码克隆到开发人员环境。

步骤 1. 转到示例应用的 GitHub 存储库(DjangoFlask),然后选择分支

按照步骤将目录分叉到 GitHub 帐户。 也可以直接将代码存储库下载到本地计算机,而无需分叉或 GitHub 帐户,但是,将无法设置本教程稍后讨论的 CI/CD。

步骤 2. 使用 git clone 命令将分叉存储库克隆到 python-container 文件夹中:

# Django
git clone https://github.com/$USERNAME/msdocs-python-django-azure-container-apps.git python-container

# Flask
# git clone https://github.com/$USERNAME/msdocs-python-flask-azure-container-apps.git python-container

步骤 3. 更改目录。

cd python-container

从 Web 应用代码生成容器映像

执行这些步骤后,你将获得一个Azure 容器注册表,其中包含从示例代码生成的 Docker 容器映像。

可以在 Azure Cloud Shell 中或装有 Azure CLI 的工作站上运行 Azure CLI 命令。

步骤 1. 使用“az group create”命令创建资源组。

az group create \
--name pythoncontainer-rg \
--location <location>

<location> 是命令az account list-locations -o table输出中的 Azure 位置名称值之一。

步骤 2. 使用 az acr create 命令创建容器注册表。

az acr create \
--resource-group pythoncontainer-rg \
--name <registry-name> \
--sku Basic \
--admin-enabled

<registry-name> 在 Azure 中必须是唯一的,并且包含 5-50 个字母数字字符。

可以使用以下命令查看为管理员创建的凭据:

az acr credential show \
--name <registry-name> \
--resource-group pythoncontainer-rg

步骤 3. 使用 az acr login 命令登录到注册表。

az acr login --name <registry-name>

该命令将“azurecr.io”添加到名称,以创建完全限定的注册表名称。 如果成功,你将看到消息“登录成功”。 如果要从与创建注册表的订阅不同的订阅访问注册表,请使用 --suffix 该开关。

步骤 4. 使用 az acr build 命令生成 映像。

az acr build \
--registry <registry-name> \
--resource-group pythoncontainer-rg \
--image pythoncontainer:latest .

请注意:

  • 命令末尾的点 (“.”) 指示要生成的源代码的位置。 如果未在示例应用根目录中运行此命令,请指定代码的路径。

  • 如果在 Azure Cloud Shell 中运行命令,则用于 git clone 首先将存储库拉入 Cloud Shell 环境,并将目录更改为项目的根目录,以便正确解释点(“.”)。

  • 如果省略 ( -t 相同 --image) 选项,命令会将本地上下文生成排入队列,而不会将其推送到注册表。 在没有推送的情况下进行生成对于映像生成的检查非常有用。

步骤 5。 使用 az acr repository list 命令确认已创建容器映像。

az acr repository list --name <registry-name>

创建 PostgreSQL 灵活服务器实例

示例应用(DjangoFlask)将餐馆评审数据存储在 PostgreSQL 数据库中。 在这些步骤中,将创建将包含数据库的服务器。

可以在 Azure Cloud Shell 中或装有 Azure CLI 的工作站上运行 Azure CLI 命令。

步骤 1. 使用 az postgres flexible-server create 命令在 Azure 中创建 PostgreSQL 服务器。 此命令运行几分钟即可完成,这并不少见。

az postgres flexible-server create \
   --resource-group pythoncontainer-rg \
   --name <postgres-server-name>  \
   --location <location> \
   --admin-user <admin-username> \
   --admin-password <admin-password> \
   --sku-name Standard_D2s_v3 \
   --public-access 0.0.0.0 
  • “pythoncontainer-rg”→本教程中使用的资源组名称。 如果使用了其他名称,请更改此值。

  • <postgres-server-name> → PostgreSQL 数据库服务器名称。 此名称在所有 Azure 中必须是唯一的。 服务器终结点为“https://< postgres-server-name.postgres.database.azure.com>”。 允许的字符为“A”-“Z”、“0”-“9”和“-”。

  • location → 使用用于 Web 应用的同一个位置。 <location> 是命令az account list-locations -o table输出中的 Azure 位置名称值之一。

  • <管理员用户名> →管理员帐户的用户名。 它不能为“azure_superuser”、“admin”、“administrator”、“root”、“guest”或“public”。 对本教程使用“demoadmin”。

  • admin-password:管理员用户的密码。 密码必须包含以下三个类别的 8 到 128 个字符:英文大写字母、英文小写字母、数字和非字母数字字符。

    重要

    创建用户名或密码 时,不使用 “$”字符。 稍后,使用这些值创建环境变量,其中“$”字符在用于运行 Python 应用的 Linux 容器中具有特殊意义。

  • <sku-name> →定价层和计算配置的名称,例如“Standard_D2s_v3”。 有关详细信息,请参阅 Azure Database for PostgreSQL 定价。 若要列出可用的 SKU,请使用 az postgres flexible-server list-skus --location <location>

  • <public-access> →使用“0.0.0.0”,它允许从任何 Azure 服务(如容器应用)公开访问服务器。

注意

如果计划使用 Azure CLI 以外的工具从本地工作站使用 PostgreSQL 服务器,则需要使用 az postgres flexible-server firewall-rule create 命令添加防火墙规则。

在服务器上创建数据库

此时,你有一个 PostgreSQL 服务器。 在本部分中,将在服务器上创建数据库。

可以在本地环境中或 Azure Cloud Shell 中使用 PostgreSQL 交互式终端 psql,该终端也可以在Azure 门户访问。 使用 psql 时,通常更容易使用 Cloud Shell ,因为 shell 中包含所有依赖项。

步骤 1. 使用 psql 连接数据库。

psql --host=<postgres-server-name>.postgres.database.azure.com \
     --port=5432 \
     --username=demoadmin@<postgres-server-name> \
     --dbname=postgres

其中 <postgres-server-name> 是 PostgreSQL 服务器的名称。 该命令将提示你输入管理员密码。

如果连接时遇到问题,请重启数据库并重试。 如果要从本地环境进行连接,必须将 IP 地址添加到数据库服务的防火墙规则列表中。

步骤 2. 创建数据库。

postgres=> 提示符下键入:

CREATE DATABASE restaurants_reviews;

命令末尾的分号(“;”)是必需的。 若要验证数据库是否已成功创建,请使用命令 \c restaurants_reviews。 键入 \? 可显示帮助,键入 \q 会退出。

还可以连接到 Azure PostgreSQL 灵活服务器,并使用 Azure Data Studio 或任何其他支持 PostgreSQL 的 IDE 创建数据库。

将 Web 应用部署到容器应用

容器应用部署到充当安全边界的容器应用 环境。 在以下步骤中,你将创建环境、环境中一个容器,并配置容器,以便网站在外部可见。

步骤 1. 根据需要登录到 Azure 并进行身份验证。

az login

步骤 2. 使用 az extension add 命令安装或升级 Azure 容器应用的扩展。

az extension add --name containerapp --upgrade

步骤 3. 使用 az containerapp env create 命令创建容器应用环境。

az containerapp env create \
--name python-container-env \
--resource-group pythoncontainer-rg \
--location <location>

<location> 是命令az account list-locations -o table输出中的 Azure 位置名称值之一。

步骤 4. 获取Azure 容器注册表的登录凭据。

az acr credential show -n <registry-name>

使用用户名和从命令输出返回的密码之一。

步骤 5。 使用 az containerapp create 命令在环境中创建容器应用。

az containerapp create \
--name python-container-app \
--resource-group pythoncontainer-rg \
--image <registry-name>.azurecr.io/pythoncontainer:latest \
--environment python-container-env \
--ingress external \
--target-port 8000 \
--registry-server <registry-name>.azurecr.io \
--registry-username <registry-username> \
--registry-password <registry-password> \
--env-vars <env-variable-string>
--query properties.configuration.ingress.fqdn

<env-variable-string> 是由键=“value”格式中的空格分隔值的字符串,具有以下值。

  • AZURE_POSTGRESQL_HOST=<postgres-server-name.postgres.database.azure.com>
  • AZURE_POSTGRESQL_DATABA标准版=restaurants_reviews
  • AZURE_POSTGRESQL_U标准版RNAME=demoadmin
  • AZURE_POSTGRESQL_PASSWORD=<db-password>
  • RUNNING_IN_PRODUCTION=1
  • AZURE_标准版CRET_KEY=<YOUR-标准版CRET-KEY>

使用输出python -c 'import secrets; print(secrets.token_hex())'生成AZURE_SECRET_KEY值。

下面是一个示例:--env-vars AZURE_POSTGRESQL_HOST="my-postgres-server.postgres.database.azure.com" AZURE_POSTGRESQL_DATABASE="restaurants_reviews" AZURE_POSTGRESQL_USERNAME="demoadmin" AZURE_POSTGRESQL_PASSWORD="somepassword" RUNNING_IN_PRODUCTION="1" AZURE_SECRET_KEY=asdfasdfasdf

步骤 7. 仅适用于 Django,迁移和创建数据库架构。 (在 Flask 示例应用中,它会自动完成,你可以跳过此步骤。

使用 az containerapp exec 命令连接:

az containerapp exec \
--name python-container-app \
--resource-group pythoncontainer-rg

然后,在 shell 命令提示符处键入 python manage.py migrate

无需迁移容器的修订。

步骤 8。 测试网站。

az containerapp create之前输入的命令将输出可用于浏览到应用的应用程序 URL。 URL 以“azurecontainerapps.io”结尾。 导航到浏览器中的 URL。 或者,可以使用 az containerapp browse 命令。

下面是添加一家餐厅和两个评论后的示例网站示例。

Screenshot showing an example of the sample website built in this tutorial.

排查部署问题

  • 你忘记了应用程序 URL 来访问网站。

    • 在Azure 门户中,转到容器应用的“概述”页并查找应用程序 URL
    • 在 VS Code 中,转到 Azure 扩展并选择“容器应用部分。 展开订阅,展开容器环境,找到容器应用时,右键单击 python-container-app 并选择“ 浏览”。
    • 在 Azure CLI 中使用命令 az containerapp show -g pythoncontainer-rg -n python-container-app --query properties.configuration.ingress.fqdn
  • 在 VS Code 中, Azure 任务中的生成映像返回错误。

    • 如果看到消息“错误:无法下载上下文。 如果 URL 不正确,请检查。“在 VS Code 输出窗口中,然后在 Docker 扩展中刷新注册表。 若要刷新,请选择 Docker 扩展,转到“注册表”部分,找到注册表并选择它。
    • 如果再次在 Azure 任务中运行生成映像,检查查看以前的运行中的注册表是否存在,如果是,请使用它。
  • 在创建容器应用期间Azure 门户中,会看到包含“无法访问 ACR'name.azurecr.io<>'”的访问错误。

    • 禁用 ACR 上的管理员凭据时,会发生此错误。 若要在门户中检查管理员状态,请转到Azure 容器注册表,选择访问密钥资源,并确保已启用管理员用户
  • 容器映像不会显示在Azure 容器注册表中。

    • 检查 Azure CLI 命令或 VS Code 输出的输出,并查找消息以确认成功。
    • 使用 Azure CLI 或在 VS Code 任务提示中检查是否已在生成命令中正确指定注册表的名称。
    • 确保凭据未过期。 例如,在 VS Code 中,在 Docker 扩展中找到目标注册表并刷新。 在 Azure CLI 中,运行 az login
  • 网站返回“错误请求(400)”。

    • 检查传递到容器的 PostgreSQL 环境变量。 400 错误通常表示 Python 代码无法连接到 PostgreSQL 实例。
    • 本教程中使用的示例代码检查容器环境变量的存在,该变量RUNNING_IN_PRODUCTION可以设置为任何值(如“1”。
  • 网站返回“未找到(404)”。

    • 容器的“概述”页上检查应用程序 URL。 如果应用程序 URL 包含“internal”一词,则入口未正确设置。
    • 检查容器的入口。 例如,在Azure 门户中,转到容器的入口资源,并确保启用 HTTP 入口,并接受来自任意位置的流量。
  • 网站不会启动,你会看到“流超时”或未返回任何内容。

    • 查看日志。
      • 在Azure 门户中,转到容器应用的修订管理资源,并检查容器的预配状态
        • 如果为“预配”,请等到预配完成。
        • 如果为“失败”,则选择修订并查看控制台日志。 选择列的顺序以显示“生成时间”、“Stream_s”和“Log_s”。 首先按最新的日志进行排序,并在“Stream_s”列中查找 Python stderrstdout 消息。 Python“print”输出将是 stdout 消息。
      • 使用 Azure CLI 时,请使用 az containerapp logs show 命令。
    • 如果使用 Django 框架,检查查看数据库中是否存在restaurants_reviews表。 否则,请使用控制台访问容器并运行 python manage.py migrate

下一步