使用 Azure Pipelines 生成 Python Web 应用并将其部署到 Azure 应用服务
Azure DevOps Services
将 Azure Pipelines 用于持续集成和持续交付 (CI/CD),以生成 Python Web 应用并将其部署到 Linux 上的 Azure 应用服务。 每当有针对存储库的提交时,管道均会自动生成 Python Web 应用并将其部署到应用服务。
在本文中,学习如何:
- 在 Azure 应用服务中创建 Web 应用。
- 在 Azure DevOps 中创建一个项目。
- 将 DevOps 项目连接到 Azure。
- 创建特定于 Python 的管道。
- 运行此管道,以在应用服务中生成应用并将其部署到 Web 应用。
先决条件
为应用代码创建存储库
在 https://github.com/Microsoft/python-sample-vscode-flask-tutorial 对 GitHub 帐户创建示例存储库分支。
在本地主机上,克隆 GitHub 存储库。 使用以下命令将 <repository-url>
替换为分支存储库的 URL。
git clone <repository-url>
在本地测试你的应用
在本地生成并运行应用,以确保其正常工作。
更改为已克隆的存储库文件夹。
cd python-sample-vscode-flask-tutorial
生成并运行应用
python -m venv .env source .env/bin/activate pip install --upgrade pip pip install -r ./requirements.txt export set FLASK_APP=hello_app.webapp python3 -m flask run
若要查看此应用,请打开浏览器窗口并转到 http://localhost:5000。 验证是否能看到标题
Visual Studio Flask Tutorial
。完成后,关闭浏览器窗口并使用 Ctrl+C 来停止 Flask 服务器。
打开 Cloud Shell
通过 https://portal.azure.com 登录到 Azure 门户。
通过选择门户工具栏上的“Cloud Shell”按钮来打开 Azure CLI。
Cloud Shell 显示在浏览器底部。 从下拉菜单中选择 Bash。
若要提供更多可用空间,请选择最大化按钮。
创建 Azure 应用服务 Web 应用
在 Azure 门户中,通过 Cloud Shell 来创建 Azure 应用服务 Web 应用。
提示
若要粘贴到 Cloud Shell,请使用 Ctrl+Shift+V,或者右键单击并从上下文菜单中选择粘贴。
使用以下命令克隆存储库,并将
<repository-url>
替换为分支存储库的 URL。git clone <repository-url>
将目录更改为已克隆的存储库文件夹,以便
az webapp up
命令将此应用识别为 Python 应用。cd python-sample-vscode-flask-tutorial
使用 az webapp up 命令预配应用服务并执行应用的首次部署。 将
<your-web-app-name>
替换为在 Azure 中保持唯一的名称。 通常,可使用个人或公司名称以及应用标识符,例如<your-name>-flaskpipelines
。 应用 URL 将成为 <你的应用服务>.azurewebsites.net。az webapp up --name <your-web-app-name>
az webapp up
命令的 JSON 输出将显示:{ "URL": <your-web-app-url>, "appserviceplan": <your-app-service-plan-name>, "location": <your-azure-location>, "name": <your-web-app-name>, "os": "Linux", "resourcegroup": <your-resource-group>, "runtime_version": "python|3.11", "runtime_version_detected": "-", "sku": <sku>, "src_path": <repository-source-path> }
记下
URL
和runtime_version
值。 在管道 YAML 文件中使用runtime_version
。URL
为 Web 应用的 URL。 可使用它来验证应用是否正在运行。注意
az webapp up
命令执行以下操作:创建一个默认的资源组。
创建一个默认的应用服务计划。
使用指定名称创建应用。
对当前工作目录中的所有文件进行 zip 部署,并启用生成自动化。
将参数本地缓存在 .azure/config 文件中,使得以后使用项目文件夹中的
az webapp up
或其他az webapp
命令部署时,无需再次指定它们。 默认情况下,自动使用缓存的值。
可使用命令参数将默认操作替换为自己的值。 有关详细信息,请参阅 az webapp up。
python-sample-vscode-flask-tutorial 应用有一个 startup.txt 文件,其中包含针对该 Web 应用的特定启动命令。 将 Web 应用
startup-file
配置属性设为startup.txt
。在
az webapp up
命令输出中,复制resourcegroup
值。使用资源组和应用名称输入以下命令。
az webapp config set --resource-group <your-resource-group> --name <your-web-app-name> --startup-file startup.txt
命令完成后,它会显示包含 Web 应用的所有配置设置的 JSON 输出。
若要查看正在运行的应用,请打开浏览器并转到
az webapp up
命令输出中显示的URL
。 如果看到一个通用页面,则请等待几秒钟以便应用服务启动,然后刷新此页面。 验证是否能看到标题Visual Studio Flask Tutorial
。
创建 Azure DevOps 项目
创建一个新的 Azure DevOps 项目。
- 在浏览器中,转到 dev.azure.com 并登录。
- 选择你的组织。
- 通过选择新建项目或创建项目(如果是在组织中创建第一个项目)来创建一个新项目。
- 输入项目名称。
- 选择项目的可见性。
- 选择创建。
- 在浏览器中,转到 Azure DevOps Server。
- 选择你的集合。
- 通过选择新建项目或创建项目(如果是在集合中创建第一个项目)来创建一个新项目。
- 输入项目名称。
- 选择项目的可见性。
- 选择创建。
创建服务主体
服务主体是创建用于应用程序、托管服务和自动化工具以访问 Azure 资源的标识。 此访问权限仅限于分配给服务主体的角色,以便控制哪些资源可供访问以及在哪个级别进行访问。
若要创建服务主体,请转到 Cloud Shell (bash) 并运行以下命令。 将 <service-principal-name>
替换为服务主体的名称、将 <your-subscription-id>
替换为订阅 ID 并将 <your-resource-group>
替换为Web 应用的资源组。
az ad sp create-for-rbac --display-name <service-principal-name> --role contributor --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>
此命令将返回类似以下示例的 JSON 对象:
{
"clientId": "<client GUID>",
"clientSecret": "<string-value>",
"subscriptionId": "<subscription GUID>",
"tenantId": "<tenant GUID>",
...
}
记下 clientId
、clientSecret
、subscriptionId
和 tenantId
值。 在下一节,需使用这些值来创建服务连接。
创建服务连接
服务连接允许你创建连接,以提供从 Azure Pipelines 到外部与远程服务的经过身份验证的访问权限。 若要部署到 Azure 应用服务 Web 应用,则请创建与包含该 Web 应用的资源组的服务连接。
在项目页面上,选择项目设置。
在此菜单的管道部分,选择服务连接。
选择创建服务连接。
选择 Azure 资源管理器,然后选择下一步。
选择身份验证方法,然后选择下一步。
在新建 Azure 服务连接对话框中,输入特定于所选身份验证方法的信息。 有关身份验证方法的详细信息,请参阅使用 Azure 资源管理器服务连接以连接到 Azure。
例如,如果使用的是工作负荷标识联合(自动)或服务主体(自动)身份验证方法,则请输入所需的信息。
字段 描述 范围级别 选择订阅。 订阅 Azure 订阅名称。 资源组 包含 Web 应用的资源组的名称。 服务连接名称 此连接的描述性名称。 向所有管道授予访问权限 选择此选项可授予对所有管道的访问权限。 选择保存。
新连接将显示在服务连接列表中,且已可在 Azure Pipelines 中使用。
在项目页面上,选择项目设置。
在此菜单的管道部分,选择服务连接。
选择创建服务连接。
选择 Azure 资源管理器,然后选择下一步。
新建 Azure 服务连接时,选择服务主体(手动),然后选择下一步
在下一对话框中,填写所需的信息。
字段 描述 环境 选择 Azure Cloud
。范围级别 选择订阅。 订阅 ID 订阅 ID。 订阅名称 Azure 订阅名称。 服务主体 ID az ad sp create-for-rbac
命令所返回 JSON 对象中的appId
值。服务主体密钥 az ad sp create-for-rbac
命令所返回 JSON 对象中的password
值。租户 ID az ad sp create-for-rbac
命令所返回 JSON 对象中的tenant
值。选择验证以验证此连接。
输入服务连接名称。
务必选中授予对所有管道的访问权限。
选择验证并保存。
新连接将显示在服务连接列表中,可供 Azure Pipelines 从项目使用。
配置自托管代理
如果使用的是自己的自托管代理,则需配置此代理以便运行 Python。 自托管代理不支持下载 Python 版本。 必须预安装 Python 版本。 使用完整的安装程序来获取与 pip 兼容的 Python 版本。
为避免出现不兼容问题,应将 Python 版本与 Azure 应用服务 Web 应用上的运行时版本进行匹配。 运行时版本会显示在 az webapp up
命令的 JSON 输出中。
需将所需的 Python 版本添加到自托管代理上的工具缓存中,以便任务可使用它。 通常,此工具缓存位于代理的 _work/_tool 目录下;或者,也可用环境变量 AGENT_TOOLSDIRECTORY 覆盖此路径。 在 tools 目录下,根据 Python 版本创建以下目录结构:
$AGENT_TOOLSDIRECTORY/
Python/
{version number}/
{platform}/
{tool files}
{platform}.complete
版本号应遵循 1.2.3 格式。 平台应为 x86 或 x64。 工具文件应为解压缩的 Python 版本文件。 {platform}.complete
应为一个 0 字节文件,它类似 x86.complete
或 x64.complete
且仅表示该工具已正确安装在缓存中。
例如,如果使用的是 64 位 Windows 计算机上的 Python 3.11,目录结构则应如下所示:
$AGENT_TOOLSDIRECTORY/
Python/
3.11.4/
x64/
{python files}
x64.complete
如果已在托管此代理的计算机上使用该 Python 版本,则可将这些文件复制到工具缓存。 如果没有该 Python 版本,则可从 Python 网站下载它。
创建管道
创建管道以生成 Python Web 应用并将其部署到 Azure 应用服务。 若要了解管道概念,请观看:
在左侧导航菜单中,选择管道。
选择 Create Pipeline。
在你的代码位于何处?对话框中,选择 GitHub。 系统可能会提示你登录 GitHub。
在选择存储库屏幕上,选择分支示例存储库。
系统可能会提示再次输入 GitHub 密码以进行确认。
如果未在 GitHub 上安装 Azure Pipelines 扩展,GitHub 则会提示你安装 Azure Pipelines 扩展。
在此页面上,向下滚动到存储库访问权限部分,选择是在所有存储库上安装此扩展还是仅在选定的存储库上安装此扩展,然后选择批准并安装。
在配置管道对话框中,选择从 Python 到 Azure 上的 Linux Web 应用。
选择 Azure 订阅,然后选择继续。
如果使用的是用户名和密码进行身份验证,则会打开浏览器以便登录到 Microsoft 帐户。
从下拉列表中选择 Web 应用名称,然后选择验证并配置。
Azure Pipelines 将创建 azure-pipelines.yml 文件,并将其显示在 YAML 管道编辑器中。 此管道文件将 CI/CD 管道定义为一系列阶段、作业和步骤,其中每个步骤均包含不同任务和脚本的详细信息。 查看管道以了解其功能。 请确保所有默认输入都适用于你的代码。
在导航菜单中,选择管道。
选择 Create Pipeline。
在你的代码位于何处对话框中,选择 GitHub Enterprise Server。 系统可能会提示你登录 GitHub。
在选择存储库选项卡上,选择分支示例存储库。
系统可能会提示再次输入 GitHub 密码以进行确认。
如果未在 GitHub 上安装 Azure Pipelines 扩展,GitHub 则会提示你安装 Azure Pipelines 扩展。
在此页面上,向下滚动到存储库访问权限部分,选择是在所有存储库上安装此扩展还是仅在选定的存储库上安装此扩展,然后选择批准并安装。
在配置管道对话框中,选择入门管道。
将 azure-pipelines.yml 文件的内容替换为以下代码。
trigger: - main variables: # Azure Resource Manager connection created during pipeline creation azureServiceConnectionId: '<your-service-connection-name>' # Web app name webAppName: '<your-web-app-name>' # Environment name environmentName: '<your-web-app-name>' # Project root folder. projectRoot: $(System.DefaultWorkingDirectory) # Python version: pythonVersion: '<your-python-version>' stages: - stage: Build displayName: Build stage jobs: - job: BuildJob pool: name: '<your-pool-name>' demands: python steps: - task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python $(pythonVersion)' - script: | python -m venv antenv source antenv/bin/activate python -m pip install --upgrade pip pip install -r requirements.txt workingDirectory: $(projectRoot) displayName: "Install requirements" - task: ArchiveFiles@2 displayName: 'Archive files' inputs: rootFolderOrFile: '$(projectRoot)' includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip replaceExistingArchive: true - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)' ArtifactName: 'drop' publishLocation: 'Container' - stage: Deploy displayName: 'Deploy Web App' dependsOn: Build condition: succeeded() jobs: - deployment: DeploymentJob pool: name: '<your-pool-name' environment: $(environmentName) strategy: runOnce: deploy: steps: - task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python version' - task: AzureWebApp@1 displayName: 'Deploy Azure Web App : <your-web-app-name>' inputs: azureSubscription: $(azureServiceConnectionId) appName: $(webAppName) package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip startUpCommand: 'startup.txt'
将以下占位符替换为自己的值:
占位符 描述 <your-service-connection-name>
已创建服务连接的名称。 <your-web-app-name>
Azure 应用服务 Web 应用的名称。 <your-pool-name>
要使用的代理池的名称。 <your-python-version>
代理上运行的 Python 版本。 最好将此版本与 Web 应用上运行的 Python 版本进行匹配。 Web 应用版本会显示在 az webapp up
命令的 JSON 输出中。
YAML 管道文件
以下说明将介绍 YAML 管道文件。 若要了解管道 YAML 文件架构,请参阅 YAML 架构参考。
完整的管道 YAML 文件示例如下所示:
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'
# Web app name
webAppName: '<your-webapp-name>'
# Agent VM image name
vmImageName: 'ubuntu-latest'
# Environment name
environmentName: '<your-webapp-name>'
# Project root folder. Point to the folder containing manage.py file.
projectRoot: $(System.DefaultWorkingDirectory)
pythonVersion: '3.11'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: BuildJob
pool:
vmImage: $(vmImageName)
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python $(pythonVersion)'
- script: |
python -m venv antenv
source antenv/bin/activate
python -m pip install --upgrade pip
pip install setup
pip install -r requirements.txt
workingDirectory: $(projectRoot)
displayName: "Install requirements"
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(projectRoot)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
displayName: 'Upload package'
artifact: drop
- stage: Deploy
displayName: 'Deploy Web App'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
strategy:
runOnce:
deploy:
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python version'
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
变量
variables
部分包含以下变量:
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'
# Web app name
webAppName: '<your-webapp-name>'
# Agent VM image name
vmImageName: 'ubuntu-latest'
# Environment name
environmentName: '<your-webapp-name>'
# Project root folder.
projectRoot: $(System.DefaultWorkingDirectory)
# Python version: 3.11. Change this to match the Python runtime version running on your web app.
pythonVersion: '3.11'
变量 | 描述 |
---|---|
azureServiceConnectionId |
Azure 资源管理器服务连接的 ID 或名称。 |
webAppName |
Azure 应用服务 Web 应用的名称。 |
vmImageName |
要用于生成代理的操作系统的名称。 |
environmentName |
在部署阶段中使用的环境的名称。 运行此阶段作业时,会自动创建环境。 |
projectRoot |
包含应用代码的根文件夹。 |
pythonVersion |
要在生成与部署代理上使用的 Python 版本。 |
variables
部分包含以下变量:
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<your-service-connection-name>'
# Web app name
webAppName: '<your-webapp-name>'
# Environment name
environmentName: '<your-webapp-name>'
# Project root folder.
projectRoot: $(System.DefaultWorkingDirectory)
# Python version: 3.11. Change this to the version that is running on your agent and web app.
pythonVersion: '3.11'
变量 | 描述 |
---|---|
azureServiceConnectionId |
Azure 资源管理器服务连接的名称。 |
webAppName |
Web 应用的名称。 |
environmentName |
在部署阶段中使用的环境的名称。 |
projectRoot |
包含应用代码的文件夹。 该值为自动系统变量。 |
pythonVersion |
要在生成与部署代理上使用的 Python 版本。 |
生成阶段
生成阶段包含在 vmImageName 变量中定义的且运行于操作系统上的单个作业。
- job: BuildJob
pool:
vmImage: $(vmImageName)
生成阶段包含一个作业,而该作业会在名称参数所标识的池中的某一代理上运行。 可使用 demands
关键字指定代理功能。 例如,demands: python
指定代理必须已安装 Python。 若要按名称指定自托管代理,可使用 demands: Agent.Name -equals <agent-name>
关键字。
- job: BuildJob
pool:
name: <your-pool-name>
demands: python
此作业包含多个步骤:
UsePythonVersion 任务可选择要使用的 Python 版本。 此版本会在
pythonVersion
变量中定义。- task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python $(pythonVersion)'
此步骤使用脚本创建虚拟 Python 环境,并安装参数中包含的
requirements.txt
workingDirectory
应用依赖项,指定应用代码的位置。- script: | python -m venv antenv source antenv/bin/activate python -m pip install --upgrade pip pip install setup pip install -r ./requirements.txt workingDirectory: $(projectRoot) displayName: "Install requirements"
ArchiveFiles 任务可创建包含 Web 应用的 .zip 存档。
.zip
文件将作为名为drop
的项目而上传到管道中。.zip
文件会在部署阶段用于将此应用部署到 Web 应用。- task: ArchiveFiles@2 displayName: 'Archive files' inputs: rootFolderOrFile: '$(projectRoot)' includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip replaceExistingArchive: true - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip displayName: 'Upload package' artifact: drop
参数 描述 rootFolderOrFile
应用代码的位置。 includeRootFolder
表示是否要在 .zip 文件中包含根文件夹。 将此参数设为 false
;否则,.zip 文件的内容会放入名为 s 的文件夹中,而 Linux 容器上的应用服务无法找到该应用代码。archiveType
要创建的存档的类型。 设置为 zip
。archiveFile
要创建的 .zip 文件的所在位置。 replaceExistingArchive
表示当此文件已存在时是否替换现有存档。 设置为 true
。upload
要上传的 .zip 文件的所在位置。 artifact
要创建的项目的名称。
部署阶段
如果生成阶段成功完成,则会运行部署阶段。 以下关键字可定义此行为:
dependsOn: Build
condition: succeeded()
部署阶段包含使用以下关键字所配置的单个部署作业:
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
关键字 | 描述 |
---|---|
deployment |
表示该作业是面向某一环境的部署作业。 |
pool |
指定部署代理池。 如果未指定此名称,则为默认代理池。 vmImage 关键字可标识代理的虚拟机映像的对应操作系统 |
environment |
指定要部署到的环境。 此运行作业时,会自动在项目中创建环境。 |
- deployment: DeploymentJob
pool:
name: <your-pool-name>
environment: $(environmentName)
关键字 | 描述 |
---|---|
deployment |
表示该作业是面向某一环境的部署作业。 |
pool 可指定要用于部署的代理池。 该池必须包含一个代理,且该代理可运行管道中指定的 Python 版本。 |
|
environment |
指定要部署到的环境。 此运行作业时,会自动在项目中创建环境。 |
strategy
关键字可用于定义部署策略。 runOnce
关键字可指定该部署作业仅运行一次。 deploy
关键字可指定要在部署作业中运行的步骤。
strategy:
runOnce:
deploy:
steps:
管道中的 steps
为:
使用 UsePythonVersion 任务来指定要在代理上使用的 Python 版本。 此版本会在
pythonVersion
变量中定义。- task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python version'
使用 AzureWebApp@1 来部署 Web 应用。 此任务会将管道项目
drop
部署到 Web 应用。- task: AzureWebApp@1 displayName: 'Deploy Azure Web App : <your-web-app-name>' inputs: azureSubscription: $(azureServiceConnectionId) appName: $(webAppName) package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
参数 描述 azureSubscription
要使用的 Azure 资源管理器服务连接 ID 或名称。 appName
Web 应用的名称。 package
要部署的 .zip 文件的所在位置。 此外,由于 python-vscode-flask-tutorial 存储库在名为 startup.txt 的文件中包含同一启动命令,因此可通过添加参数
startUpCommand: 'startup.txt'
来指定该文件。
管道中的 steps
为:
使用 UsePythonVersion 任务来指定要在代理上使用的 Python 版本。 此版本会在
pythonVersion
变量中定义。- task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python version'
使用 AzureWebApp@1 来部署 Web 应用。 此任务会将管道项目
drop
部署到 Web 应用。- task: AzureWebApp@1 displayName: 'Deploy Azure Web App : <your-web-app-name>' inputs: azureSubscription: $(azureServiceConnectionId) appName: $(webAppName) package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
参数 描述 azureSubscription
要使用的 Azure 资源管理器服务连接 ID 或名称。 appName
Web 应用的名称。 package
要部署的 .zip 文件的所在位置。 此外,由于 python-vscode-flask-tutorial 存储库在名为 startup.txt 的文件中包含同一启动命令,因此可通过添加参数
startUpCommand: 'startup.txt'
来指定该文件。- task: AzureWebApp@1 displayName: 'Deploy Azure Web App : $(webAppName)' inputs: azureSubscription: $(azureServiceConnectionId) appName: $(webAppName) package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip startUpCommand: 'startup.txt'
参数 描述 azureSubscription
要使用的 Azure 资源管理器服务连接 ID 或名称。 appName
Web 应用的名称。 package
要部署的 .zip 文件的所在位置。 startUpCommand
部署应用后要运行的命令。 此示例应用使用 startup.txt
。
运行管道
你现在可以试用了!
在编辑器中,选择保存并运行。
在保存并运行对话框中,添加提交消息,然后选择保存并运行。
可通过在管道运行摘要中选择“阶段”或“作业”来监视运行中的管道。
每个成功完成的阶段和作业旁均有绿色复选标记。 如果出现错误,它们则会显示在摘要或作业步骤中。
通过选择摘要页面右上方的垂直点并选择编辑管道,可快速返回到 YAML 编辑器:
在部署作业中,选择部署 Azure Web 应用任务可显示其输出。 若要访问已部署的站点,请按住 Ctrl 键并选择
App Service Application URL
之后的 URL。如果使用的是示例应用,则该应用应显示如下内容:
重要
如果应用因缺少依赖项而失败,则部署期间不会处理 requirements.txt 文件。 如果直接在门户上创建了 Web 应用,而不是如本文所示使用 az webapp up
命令,则会发生此行为。
az webapp up
命令专门将生成操作 SCM_DO_BUILD_DURING_DEPLOYMENT
设置为 true
。 如果已通过门户预配应用服务,则不会自动设置此操作。
以下步骤用于设置操作:
- 打开 Azure 门户,选择“应用服务”,然后选择配置。
- 在应用程序设置选项卡下,选择新建应用程序设置。
- 在显示的弹出窗口中,将名称设置为
SCM_DO_BUILD_DURING_DEPLOYMENT
,将值设置为true
,然后选择确定。 - 选择配置页顶部的保存。
- 再次运行管道。 应在部署期间安装依赖项。
触发管道运行
若要触发管道运行,请将某一更改提交到此存储库。 例如,可向该应用添加新功能,或更新该应用的依赖项。
- 转到 GitHub 存储库。
- 更改代码,例如更改此应用的标题。
- 将此更改提交到存储库。
- 转到管道并验证是否已创建新运行。
- 运行完成后,验证新生成是否已部署到 Web 应用。
- 在 Azure 门户中,转到自己的 Web 应用。
- 选择部署中心,然后选择日志选项卡。
- 验证是否已列出新部署。
Django 的注意事项
如果使用的是单独的数据库,则可使用 Azure Pipelines 将 Django 应用部署到 Linux 上的 Azure 应用服务。 不能使用 SQLite 数据库,因为应用服务会锁定 db.sqlite3 文件,从而阻止读取和写入。 此行为不会影响外部数据库。
如在应用服务上配置 Python 应用 - 容器启动过程中所述,应用服务在应用代码中自动查找 wsgi.py 文件,该文件通常包含应用对象。 如果你要以任何方式自定义启动命令,请在 YAML 管道文件的 AzureWebApp@1
步骤中使用 startUpCommand
参数,如上一部分所述。
使用 Django 时,通常需要在部署应用代码后使用 manage.py migrate
迁移数据模型。 为此,可使用部署后脚本添加 startUpCommand
。 例如,下面是 AzureWebApp@1 任务中的 startUpCommand
属性。
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
startUpCommand: 'python manage.py migrate'
在生成代理上运行测试
生成过程中,你可能想对应用代码运行测试。 由于测试会在生成代理上运行,因此需将依赖项安装到生成代理的虚拟环境中。 测试运行后,请先删除虚拟环境,然后再创建用于部署的 .zip 文件。 以下脚本元素演示了此过程。 将它们放在 azure-pipelines.yml 文件中的 ArchiveFiles@2
任务之前。 有关详细信息,请参阅运行跨平台脚本。
# The | symbol is a continuation character, indicating a multi-line script.
# A single-line script can immediately follow "- script:".
- script: |
python -m venv .env
source .env/bin/activate
pip install setuptools
pip install -r requirements.txt
# The displayName shows in the pipeline UI when a build runs
displayName: 'Install dependencies on build agent'
- script: |
# Put commands to run tests here
displayName: 'Run tests'
- script: |
echo Deleting .env
deactivate
rm -rf .env
displayName: 'Remove .env before zip'
此外,还可使用 PublishTestResults@2 等任务将测试结果发布到管道。 有关详细信息,请参阅生成 Python 应用 - 运行测试。
清理资源
为避免在本教程中创建的 Azure 资源产生费用,请执行以下操作:
删除所创建的项目。 删除此项目会同时删除管道和服务连接。
删除包含应用服务和应用服务计划的 Azure 资源组。 在 Azure 门户中,转到资源组,选择删除资源组,然后按提示进行操作。
删除用于维护 Cloud Shell 的文件系统的存储帐户。 关闭 Cloud Shell,然后转到以 cloud-shell-storage- 开头的资源组,选择删除资源组,然后按提示进行操作。