将 CI/CD 与 GitHub Actions 配合使用以将 Python Web 应用部署到 Linux 上的 Azure 应用服务

使用 GitHub Actions 持续集成和持续交付(CI/CD)平台将 Python Web 应用部署到 Linux 上的Azure App 服务。 GitHub Actions 工作流会自动生成代码,并在向存储库提交时将其部署到App 服务。 可以在 GitHub Actions 工作流中添加其他自动化,例如测试脚本、安全检查和多阶段部署。

为应用代码创建存储库

如果已有要使用的 Python Web 应用,请确保已将其提交到 GitHub 存储库。

如果需要使用应用,可以在 https://github.com/Microsoft/python-sample-vscode-flask-tutorial 中创建存储库的分支和克隆。 代码来自 Visual Studio Code 中的 Flask 教程。

注意

如果你的应用使用 Django 和 SQLite 数据库,则不适用于本教程。 如果 Django 应用使用单独的数据库(如 PostgreSQL),则可以将其与本教程一起使用。 有关 Django 的详细信息,请参阅 本文后面的 Django 注意事项。

创建目标Azure App 服务

创建App 服务实例的最快方法是通过交互式 Azure Cloud Shell 使用 Azure 命令行接口(CLI)。 Cloud Shell 包括 Git 和 Azure CLI。 在以下步骤中,你将使用 az webapp,同时创建App 服务并执行应用的第一个部署。

步骤 1.https://portal.azure.com 中登录 Azure 门户。

步骤 2. 通过选择门户工具栏上的 Cloud Shell 图标打开 Azure CLI。

Screenshot showing how to open Azure Cloud Shell in Azure portal.

步骤 3. 在 Cloud Shell 中,从下拉列表中选择 Bash。

Screenshot showing an Azure Cloud Shell Bash shell in Azure portal.

步骤 4. 在 Cloud Shell 中,使用 git 克隆克隆存储库。 例如,如果使用 Flask 示例应用,则命令为:

git clone https://github.com/<github-user>/python-sample-vscode-flask-tutorial.git

将 github-user> 替换为<创建存储库分支的 GitHub 帐户的名称。 如果使用其他应用存储库,则此存储库是设置 GitHub Actions 的位置。

注意

Cloud Shell 由名为 cloud-shell-storage-<你所在的区域> 的资源组中的 Azure 存储帐户提供支持。 该存储帐户包含 Cloud Shell 文件系统的映像,用于存储克隆的存储库。 此存储的成本很低。 可以删除本文末尾的存储帐户以及创建的其他资源。

提示

若要粘贴到 Cloud Shell,请使用 Ctrl+Shift+V,或者右键单击并从上下文菜单中选择“粘贴”。

步骤 5。 在 Cloud Shell 中,将目录更改为包含 Python 应用的存储库文件夹,以便 az webapp up 命令将应用识别为 Python。 例如,对于 Flask 示例应用:

cd python-sample-vscode-flask-tutorial

步骤 6. 在 Cloud Shell 中,使用 az webapp up 创建App 服务并最初部署应用。

az webapp up --name <app-service-name> --runtime "PYTHON:3.9"

指定在 Azure 中唯一的App 服务名称。 名称长度必须为 3-60 个字符,只能包含字母、数字和连字符。 名称必须以字母开头,并且必须以字母或数字结尾。

用于 az webapp list-runtimes 获取可用运行时的列表。 使用 PYTHON|X.Y 格式,其中 X.Y 是 Python 版本。

还可以使用--location参数指定App 服务的位置。 az account list-locations --output table使用命令获取可用位置的列表。

步骤 7. 如果应用使用自定义启动命令,请使用 az webapp config 使用该命令。 如果应用没有自定义启动命令,请跳过此步骤。

例如, python-sample-vscode-flask-tutorial 应用包含名为 startup.txt 的文件,其中包含一个启动命令,可以使用以下命令:

az webapp config set \
  --resource-group <resource-group-name> \
  --name <app-service-name> \
  --startup-file startup.txt

可以从上一 az webapp up 命令的输出中找到资源组名称。 资源组名称以 azure-account-name_rg_开头<。>

步骤 8。 若要查看正在运行的应用,请打开浏览器并转到 http:// app-service-name.azurewebsites.net>。<

如果看到一个通用页,请等待几秒钟,等待应用服务开始,然后刷新页。 如果继续看到通用页面,检查从正确的文件夹部署。 例如,如果使用 Flask 示例应用,则文件夹为 python-sample-vscode-flask-tutorial。 此外,对于 Flask 示例应用,检查正确设置启动命令。

在 App 服务 中设置持续部署

在以下步骤中,你将设置持续部署(CD),这意味着在触发工作流时会发生新的代码部署。 本教程中的触发器是对存储库的主分支的任何更改,例如使用 拉取请求 (PR)。

第 1 步。 使用 az webapp deployment github-actions add 命令添加 GitHub Action。

az webapp deployment github-actions add \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

--login-with-github 参数使用交互式方法检索个人访问令牌。 按照提示完成身份验证。

如果存在与App 服务使用的名称冲突的现有工作流文件,系统会要求你选择是否覆盖。 --force使用参数在不询问的情况下覆盖。

add 命令的作用:

  • 在存储库中创建新的工作流文件:.github/workflows/<workflow-name.yml>;文件的名称将包含App 服务的名称。
  • 提取包含App 服务机密的发布配置文件,并将其添加为 GitHub 操作机密。 机密的名称以 AZUREAPP 开头标准版RVICE_PUBLISHPROFILE_。 此机密在工作流文件中引用。

步骤 2. 使用 az webapp deployment source show 命令获取源代码管理部署配置的详细信息。

az webapp deployment source show \
  --name <app-service-name> \
  --resource-group <resource-group-name>

在命令的输出中,确认属性的值repoUrlbranch。 这些值应与上一步中指定的值匹配。

GitHub 工作流和操作说明

工作流由存储库中 /.github/workflows/ 路径中的 YAML (.yml) 文件定义。 此 YAML 文件包含构成工作流的各种步骤和参数,这是与 GitHub 存储库关联的自动化过程。 可以使用工作流在 GitHub 上生成、测试、打包、发布和部署任何项目。

每个工作流由一个或多个作业组成。 每个作业反过来都是一组步骤。 最后,每个步骤都是 shell 脚本或操作。

对于使用用于部署到App 服务的 Python 代码设置的工作流,工作流具有以下操作:

操作 说明
检查out 查看运行程序(GitHub Actions 代理)上的存储库。
setup-python 在运行程序上安装 Python。
appservice-build 生成 Web 应用。
webapps-deploy 使用发布配置文件凭据在 Azure 中部署 Web 应用进行身份验证。 凭据存储在 GitHub 机密

用于创建工作流的工作流模板是 Azure/actions-workflow-samples

工作流在将事件推送到指定的分支时触发。 事件和分支在工作流文件的开头定义。 例如,以下代码片段显示工作流是在将事件推送到主分支时触发的

on:
  push:
    branches:
    - main

OAuth 授权的应用

设置持续部署时,可将Azure App 服务授权为 GitHub 帐户的授权 OAuth 应用。 App 服务使用授权的访问权限在 .github/workflows/<workflow-name.yml> 中创建 GitHub 操作 YML 文件。 可以在集成/应用程序下查看授权的应用,并在 GitHub 帐户设置下撤销权限。

Screenshot showing how to view authorized OAuth Apps for a GitHub account.

工作流发布配置文件机密

在添加到存储库的 .github/workflows/<workflow-name.yml> 工作流文件中,你将看到用于发布工作流部署作业所需的配置文件凭据的占位符。 发布配置文件信息存储在存储库设置的安全/操作

Screenshot showing how to view action secrets in GitHub.

在本文中,GitHub 操作使用发布配置文件凭据进行身份验证。 可通过其他方法(例如使用服务主体或 OpenID 连接)进行身份验证。 有关详细信息,请参阅使用 GitHub Actions 部署到App 服务。

运行工作流

现在,你将通过更改存储库来测试工作流。

步骤 1. 转到示例存储库(或使用的存储库)的分支,然后选择作为触发器的一部分设置的分支。

Screenshot showing how to go to the repo and branch where the GitHub Actions workflow is defined.

步骤 2. 做一个小的改变。

例如,如果使用 VS Code Flask 教程,则可以

  • 转到 触发器分支的 /hello-app/templates/home.html 文件。
  • 选择“ 编辑 ”并添加文本“已重新部署!”。

步骤 3. 将更改直接提交到正在使用的分支。

  • 在正在编辑的页面右上角,选择“ 提交更改...” 按钮。 “ 提交更改 ”窗口随即打开。 在“提交更改”窗口中,根据需要修改提交消息,然后选择“提交更改”按钮。
  • 提交将启动 GitHub Actions 工作流。

还可以手动启动工作流。

第 1 步。 转到 为持续部署设置的存储库的“操作 ”选项卡。

第 2 步。 在工作流列表中选择工作流,然后选择“ 运行工作流”。

排查工作流失败的问题

若要检查工作流的状态,请转到存储库的“操作”选项卡。 在钻取本教程中创建的工作流文件时,你将看到两个作业“生成”和“部署”。 对于失败的作业,请查看作业任务的输出,了解失败的指示。 常见问题如下:

  • 如果应用由于缺少依赖项而失败,则 部署期间未处理 requirements.txt 文件。 如果直接在门户上创建了 Web 应用,而不是如本文所示使用 az webapp up 命令,则会发生此行为。

  • 如果通过门户预配了应用服务,则可能尚未设置生成操作SCM_DO_BUILD_DURING_DEPLOYMENT设置。 此设置必须设置为 true。 该 az webapp up 命令会自动设置生成操作。

  • 如果看到带有“TLS 握手超时”的错误消息,请在存储库的“操作”选项卡下选择“触发自动部署”来手动运行工作流,以查看超时是否是临时问题。

  • 如果为容器应用设置持续部署,如本教程所示,则最初会自动为你创建工作流文件(.github/workflows/<workflow-name.yml>)。 如果修改了它,请删除修改,以查看它们是否导致失败。

运行部署后脚本

例如,部署后脚本可以定义应用代码所需的环境变量。 将脚本添加为应用代码的一部分,并使用启动命令执行该脚本。

若要避免在工作流 YML 文件中对变量值进行硬编码,可以在 GitHub Web 界面中改写变量值,然后在脚本中引用变量名称。 可以为存储库或环境(帐户存储库)创建加密机密。 有关详细信息,请参阅 GitHub Docs 中的加密机密。

Django 的注意事项

如本文前面所述,如果使用单独的数据库,可以使用 GitHub Actions 将 Django 应用部署到 Linux 上的Azure App 服务。 不能使用 SQLite 数据库,因为应用服务会锁定 db.sqlite3 文件,从而阻止读取和写入。 此行为不会影响外部数据库。

配置 Python 应用一文中所述,App 服务会自动在应用代码(通常包含应用对象)中查找 wsgi.py 文件。 使用 webapp config set 命令设置启动命令时,使用 --startup-file 参数指定包含应用对象的文件。 该 webapp config set 命令在 webapps-deploy 操作中不可用。 相反,可以使用 startup-command 参数来指定启动命令。 例如,以下代码片段演示如何在工作流文件中指定启动命令:

startup-command: startup.txt

使用 Django 时,通常需要在部署应用代码后使用 python manage.py migrate 命令迁移数据模型。 可以在部署后脚本中运行 migrate 命令。

断开 GitHub Actions 的连接

断开 gitHub Actions 与App 服务的连接,可以重新配置应用部署。 可以在断开连接后选择工作流文件会发生什么情况,无论是保存还是删除文件。

使用 Azure CLI az webapp deployment github-actions remove 命令断开 GitHub Actions 的连接。

az webapp deployment github-actions remove \
  --repo "<github-user>/<github-repo>" \
  --resource-group <resource-group-name> \
  --branch <branch-name> \
  --name <app-service-name> \
  --login-with-github

清理资源

为了避免在本教程中创建的 Azure 资源产生费用,请删除包含应用服务和应用服务计划的资源组。

在安装 Azure CLI(包括 Azure Cloud Shell)的任何位置,都可以使用 az group delete 命令删除资源组。

az group delete --name <resource-group-name>

若要删除维护 Cloud Shell 文件系统的存储帐户(每月会产生少量费用),请删除以“cloud-shell-storage-”开头的资源组。 如果你是组的唯一用户,则删除资源组是安全的。 如果有其他用户,则可以删除资源组中的存储帐户。

如果删除了 Azure 资源组,请考虑对已连接进行持续部署的 GitHub 帐户和存储库进行以下修改:

  • 在存储库中,删除 .github/workflows/<workflow-name.yml> 文件。
  • 在存储库设置中,删除为工作流创建的 AZUREAPP标准版RVICE_PUBLISHPROFILE_密钥。
  • 在 GitHub 帐户设置中,删除Azure App 服务作为 GitHub 帐户的授权 Oauth 应用。