直接从 ZIP 包运行 Azure 应用服务中的应用

注意

Python 应用不支持从包运行。 部署 Python 代码的 ZIP 文件时,需要设置一个标志以启用 Azure生成自动化。 生成自动化将为应用创建 Python 虚拟环境,并安装所需的任何必要要求和包。 有关更多详细信息,请参阅生成自动化

Azure 应用服务中,可以直接从部署 ZIP 包文件运行应用。 本文将介绍如何在应用中启用此功能。

应用服务中的所有其他部署方法具有一定的共同之处:文件将部署到应用中的 D:\home\site\wwwroot(或 Linux 应用的 /home/site/wwwroot)。 由于应用在运行时使用同一个目录,因此部署可能会因文件锁定冲突而失败,并且应用可能会由于某些文件尚未更新而出现不可预测的行为。

相反,直接从包运行时,包中的文件不会复制到 wwwroot 目录, 而是将 ZIP 包本身直接装载为只读的 wwwroot 目录。 从包直接运行可提供多种好处:

  • 消除部署与运行时之间的文件锁定冲突。
  • 确保在任意时候只运行完全部署的应用。
  • 可部署到生产应用(需重启)。
  • 改善 Azure 资源管理器部署的性能。
  • 可以减少冷启动时间,特别是对于具有大型 npm 包树的 JavaScript 函数。

注意

目前仅支持 ZIP 包文件。

创建一个项目 ZIP 包

重要

为部署创建 ZIP 包时,不要包含根目录,应只包含其中的文件和目录。 如果将 GitHub 存储库下载为 ZIP 文件,无法将该文件按原样部署到应用服务。 GitHub 可在顶层添加额外的嵌套目录,但这不适用于应用服务。

在本地终端窗口中,导航到应用项目的根目录。

此目录应包含 Web 应用的入口文件,例如 index.htmlindex.phpapp.js。 它还可能包含包管理文件,如 project.jsoncomposer.jsonpackage.jsonbower.jsonrequirements.txt

除非你希望应用服务为你运行部署自动化,否则请运行所有生成任务(例如,npmbowergulpcomposerpip),并确保你拥有运行应用所需的所有文件。 如果想要直接运行包,则此步骤是必需的。

创建一个包含项目所有内容的 zip 文件。 对于 dotnet 项目,这是 dotnet publish 命令的输出目录中的所有内容(不包含输出目录本身)。 例如,在终端中使用以下命令创建包含当前目录内容的 ZIP 包:

# Bash
zip -r <file-name>.zip .

# PowerShell
Compress-Archive -Path * -DestinationPath <file-name>.zip

启用从包运行的功能

WEBSITE_RUN_FROM_PACKAGE 应用设置启用从包运行的功能。 若要指定此设置,请使用 Azure CLI 运行以下命令。

az webapp config appsettings set --resource-group <group-name> --name <app-name> --settings WEBSITE_RUN_FROM_PACKAGE="1"

WEBSITE_RUN_FROM_PACKAGE="1" 允许从应用本地的包运行应用。 也可以从远程包运行

运行包

在应用服务中运行包的最简单方法是使用 Azure CLI az webapp deployment source config-zip 命令。 例如:

az webapp deploy --resource-group <group-name> --name <app-name> --src-path <filename>.zip

由于已指定 WEBSITE_RUN_FROM_PACKAGE 应用设置,因此,此命令不会将包内容解压缩到应用的 D:\home\site\wwwroot 目录。 而是将 ZIP 文件按原样上传到 D:\home\data\SitePackages,并在同一目录中创建 packagename.txt,其中包含要在运行时加载的 ZIP 包的名称。 如果以不同的方式(例如使用 FTP)上传 ZIP 包,需要手动创建 D:\home\data\SitePackages 目录和 packagename.txt 文件。

该命令还会重启应用。 由于设置了 WEBSITE_RUN_FROM_PACKAGE,应用服务会将上传的包装载为只读的 wwwroot 目录,并直接从该装载目录运行应用。

改为从外部 URL 运行

还可以从外部 URL(例如 Azure Blob 存储)运行包。 可以使用 Azure 存储资源管理器将包文件上传到 Blob 存储帐户。 应使用带共享访问签名 (SAS) 的专用存储容器或使用托管标识,使应用服务运行时能够安全访问包。

将文件上传到 Blob 存储并获取该文件的 SAS URL 后,请将 WEBSITE_RUN_FROM_PACKAGE 应用设置指定为该 URL。 以下示例使用 Azure CLI 执行此操作:

az webapp config appsettings set --name <app-name> --resource-group <resource-group-name> --settings WEBSITE_RUN_FROM_PACKAGE="https://myblobstorage.blob.core.chinacloudapi.cn/content/SampleCoreMVCApp.zip?st=2018-02-13T09%3A48%3A00Z&se=2044-06-14T09%3A48%3A00Z&sp=rl&sv=2017-04-17&sr=b&sig=bNrVrEFzRHQB17GFJ7boEanetyJ9DGwBSV8OM3Mdh%2FM%3D"

如果将同名的已更新包发布到 Blob 存储,则需要重启应用,以便将更新的包加载到应用服务中。

使用托管标识访问 Azure Blob 存储中的包

可以将 Azure Blob 存储配置为使用 Azure AD 授权请求。 这意味着,可以依赖应用程序的托管标识,而不是生成会过期的 SAS 密钥。 默认情况下,将使用应用的系统分配标识。 如果要指定用户分配的标识,可以将 WEBSITE_RUN_FROM_PACKAGE_BLOB_MI_RESOURCE_ID 应用设置设为该标识的资源 ID。 该设置还可以接受“SystemAssigned”作为值,尽管这与完全省略该设置是一样的。

若要使用标识提取包,请运行以下操作:

  1. 确保 Blob 已配置为私有访问

  2. 向标识授予存储 Blob 数据读取器角色,其范围为包 blob。 有关创建角色分配的详细信息,请参阅分配 Azure 角色以访问 Blob 数据

  3. WEBSITE_RUN_FROM_PACKAGE 应用程序设置设为包的 blob URL。 格式可能为“https://{storage-account-name}.blob.core.chinacloudapi.cn/{container-name}/{path-to-package}”或类似格式。

从包中运行时部署 WebJob 文件

当你启用从包中运行应用时,有两种方法可用来部署 WebJob 文件:

  • 在你的应用所在的 ZIP 包中部署:就像平时那样将它们包括在 <project-root>\app_data\jobs\... 中(这将映射到 WebJobs 快速入门中指定的部署路径 \site\wwwroot\app_data\jobs\...)。
  • 从你的应用的 ZIP 包中单独部署:由于平常的部署路径 \site\wwwroot\app_data\jobs\... 现在是只读的,因此你无法在此处部署 WebJob 文件。 请将 WebJob 文件部署到非只读的 \site\jobs\...。 部署到 \site\wwwroot\app_data\jobs\...\site\jobs\... 的 WebJobs 都会运行。

注意

\site\wwwroot 成为只读的后,诸如创建 disable.job 之类的操作将会失败。

疑难解答

  • 直接从包运行会使 wwwroot 变为只读目录。 如果应用尝试将文件写入此目录,将会收到错误。
  • 不支持 TAR 和 GZIP 格式。
  • ZIP 文件最大可以为 1GB
  • 此功能与本地缓存不兼容。
  • 若要提高冷启动性能,请使用本地 Zip 选项 (WEBSITE_RUN_FROM_PACKAGE=1)。

更多资源