通过CI/CD管道部署Azure Function与VSCode部署的差异问题
通过Azure订阅的CI/CD管道部署Azure Python Function App后,在Azure Function门户出现提示:
Your app is currently in read only mode because you are running from a package file. To make any changes update the content in your zip file and WEBSITE_RUN_FROM_PACKAGE app setting.
(您的应用当前处于只读模式,因为您正从包文件运行。如需修改,请更新zip文件内容及WEBSITE_RUN_FROM_PACKAGE应用设置)
但通过VSCode部署该函数应用时不会出现此问题,尝试修改WEBSITE_RUN_FROM_PACKAGE相关应用设置后问题仍存在,询问消费型应用通过CI/CD门户部署是否存在缺陷,附带的CI/CD管道配置如下:
parameters: - name: environment type: string default: D values: - D - Q - P trigger: - none variables: azureSubscription: 'xxxx' buildPlatform: 'Any CPU' buildConfiguration: 'Release' appName: 'xxxxxx' resources: repositories: - repository: self type: git ref: refs/heads/feature-cdqpipeline_upd jobs: - job: Job_1 displayName: Agent job 1 pool: vmImage: ubuntu-latest steps: - checkout: self fetchDepth: 1 - task: Bash@3 displayName: Build extensions inputs: targetType: inline script: >- if [ -f extensions.csproj ] then dotnet build extensions.csproj --output ./bin fi - task: UsePythonVersion@0 displayName: Use Python 3.9 inputs: versionSpec: 3.9 allowUnstable: true - task: Bash@3 displayName: Install Application Dependencies inputs: targetType: inline script: >- python3.9 -m venv worker_venv source worker_venv/bin/activate pip3.9 install setuptools pip3.9 install -r requirements.txt - task: ArchiveFiles@2 displayName: Archive files inputs: rootFolderOrFile: AzFunct includeRootFolder: false - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact: drop' - task: AzureFunctionApp@1 # Add this at the end of your file inputs: azureSubscription: '${{variables.azureSubscription}}' appType: functionAppLinux # default is functionApp appName: 'xxxxxxxx' package: $(System.ArtifactsDirectory)/**/*.zip deploymentMethod: 'zipDeploy' #Uncomment the next lines to deploy to a deployment slot #Note that deployment slots is not supported for Linux #deployToSlotOrASE: true #resourceGroupName: '<Resource Group Name>' #slotName: '<Slot name>' ...
这不是消费型应用CI/CD部署的缺陷,而是两种部署方式的机制差异导致的:
1. 两种部署方式的核心区别
VSCode部署默认用的是文件同步模式,直接把文件上传到应用的文件系统,不会触发WEBSITE_RUN_FROM_PACKAGE设置;而你的CI/CD管道用了zipDeploy部署方式,这种方式会自动给应用设置WEBSITE_RUN_FROM_PACKAGE=1,让应用从包文件运行,自然就进入了只读模式。
2. 解决只读模式的两种方案
方案一:切换到文件同步部署
在AzureFunctionApp@1任务里,把deploymentMethod改成不会触发包运行的方式,或者直接用AzureRmWebAppDeployment@4任务替代,配置成文件系统部署:
- task: AzureRmWebAppDeployment@4 inputs: ConnectionType: 'AzureRM' azureSubscription: '${{variables.azureSubscription}}' appType: 'functionAppLinux' WebAppName: 'xxxxxxxx' packageForLinux: '$(System.ArtifactsDirectory)/**/*.zip' deployToSlotOrASE: false DeploymentType: 'webDeploy' # 基于文件系统的部署方式
方案二:保留包部署模式,通过CI/CD更新内容
包部署模式其实性能更优,冷启动速度更快,不需要强行修改WEBSITE_RUN_FROM_PACKAGE。后续所有代码变更直接通过CI/CD管道重新打包部署就行,门户里的代码编辑功能本来就不适合生产环境,所有变更都应该走版本控制+CI/CD的流程。
3. 手动修改WEBSITE_RUN_FROM_PACKAGE不生效的排查
如果手动改了应用设置但没效果,大概率是CI/CD管道部署时又把这个设置覆盖了。可以在AzureFunctionApp@1任务里明确指定该设置的值,比如禁用包运行模式:
- task: AzureFunctionApp@1 inputs: # 其他原有参数... appSettings: '-WEBSITE_RUN_FROM_PACKAGE ""' # 清空该设置
注意:Linux函数应用修改这个设置后,必须重启应用才能生效。
内容的提问来源于stack exchange,提问作者Anshul Dubey

