Two identical Azure deployments; one always throws 404 - how to find out what the difference is?
We found out what was wrong. It was not an Azure issue. The problem was that we were deploying a bad ZIP file. The ZIP file was missing web.config, which meant that the web application could not start up.
We were zipping our published web application by having this in the CSPROJ file:
&lt;Target Name=&quot;ZipOutputPath&quot; AfterTargets=&quot;Publish&quot;&gt;
  &lt;ZipDirectory SourceDirectory=&quot;$(OutputPath)\publish&quot; DestinationFile=&quot;$(MSBuildProjectDirectory)\kmswebapp.zip&quot; Overwrite=&quot;true&quot; /&gt;
&lt;/Target&gt;

This turned out not to work because the compiler does things in a different order than we expected. At the time when it generated the ZIP file, web.config was not generated yet, so web.config never got packed into the ZIP file. Hence Azure could not start the application.
When we deployed from our local machines, it worked because we didn't clean the publish directory before each run, so there would be a web.config left over from the previous run, and this old (but unchanged) web.config would get packed into the ZIP file and deployed to Azure, so Azure would know how to start the application.
We solved it by removing the above from our CSPROJ file and doing (roughly) this in our Jenkinsfile:
powershell &quot;dotnet publish ./src/webapi/WebAPI.csproj&quot;
powershell &quot;if (!(Test-Path('${publishDirectoryPath}/web.config'))){throw 'We need web.config to exist in the publish directory'}&quot;
powershell &quot;Compress-Archive -Path '${publishDirectoryPath}/*' -DestinationPath './src/webapi/kmswebapp.zip' -Force&quot;

This generates a proper ZIP file including web.config, and Azure can now start our application so it can respond properly to requests.