What is going wrong with web deployment from Visual Studio and App service?

Suddenly Web Deployment started failing.

Could not find file 'D:\home\site\wwwroot\App_Offline.htm'.

I stopped the service, but deployment still fails.

When I tried to delete any file from wwwroot in Kudu PowerShell UI I get error "404 file not find", but that file is still displayed after refresh. When I tried to delete file directly in powershell I get error

Cannot remove item D:\home\site\wwwroot\Azure.Storage.dll: Invalid access to memory location.
At line:1 char:1
+ del .\Azure.Storage.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (D:\home\site\wwwroot\Azure.Storage. 
   dll:FileInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell 
   .Commands.RemoveItemCommand

I deleted the service, recreated it and the first deployment from Visual Studio was Ok. But next day deployment failed again. The only thing between that deployments was deployment from VSTS. But I was able to deploy from VSTS and from Visual Studio in any order before without any problem.

I'm the Owner of that App Service.

Deployment log.

(2018-08-06 13:05:03) An error occurred when the request was processed on the remote computer.
Could not find file 'D:\home\site\wwwroot\App_Offline.htm'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync)
   at System.Xml.XmlWriterSettings.CreateWriter(String outputFileName)
   at System.Xml.XmlWriter.Create(String outputFileName, XmlWriterSettings settings)
   at Microsoft.Web.Deployment.AppOfflineRuleHandler.AddAppOfflineFilesToEachApp(DeploymentBaseContext baseContext, Boolean whatIf)
   at Microsoft.Web.Deployment.AppOfflineRuleHandler.AddChild(DeploymentSyncContext syncContext, DeploymentObject destinationParentObject, DeploymentObject& sourceObject, Boolean& proceed)
   at Microsoft.Web.Deployment.DeploymentSyncContext.HandleAddChild(DeploymentObject destParent, DeploymentObject sourceObject, Int32 position)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncDirPathChildren(DeploymentObject destRoot, DeploymentObject sourceRoot)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildren(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildrenNoOrder(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildren(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildrenNoOrder(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildren(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildrenOrder(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.SyncChildren(DeploymentObject dest, DeploymentObject source)
   at Microsoft.Web.Deployment.DeploymentSyncContext.ProcessSync(DeploymentObject destinationObject, DeploymentObject sourceObject)
   at Microsoft.Web.Deployment.DeploymentObject.SyncToInternal(DeploymentObject destObject, DeploymentSyncOptions syncOptions, PayloadTable payloadTable, ContentRootTable contentRootTable, Nullable`1 syncPassId, String syncSessionId)
   at Microsoft.Web.Deployment.DeploymentAgent.HandleSync(DeploymentAgentAsyncData asyncData, Nullable`1 passId, String user, String siteName)
Publish failed to deploy.

Solution 1:

All of a sudden VSTS default deployment mode became Run-From-Zip.

The solution is setting Select deployment method checkbox in VSTS deploy and be sure Web Deploy is selected.

To "unlock" the service you need to delete setting WEBSITE_RUN_FROM_PACKAGE from Application settings page in the Azure Portal - it is under 'Configuration'

enter image description here

Solution 2:

I hade the same problem today with net core 2.2 and the solution was to remove setting "WEBSITE_RUN_FROM_PACKAGE" in azure appsettings

Solution 3:

We got hit by this same issue - the file system becomes readonly when WEBSITE_RUN_FROM_PACKAGE=1. Azure App Service seems to be adding this app setting automatically during recent platform upgrades.

I do suggest using Run-From-Package over web deploy - but you can easily revert their forced updates by setting WEBSITE_RUN_FROM_PACKAGE=0. If you are on Azure DevOps - the latest version of App Service Deploy v4 supports Run-From-Package.

Solution 4:

The reason for this is because the AzureWebApp task in Azure DevOps (VSTS) Pipeline, updates the 'WEBSITE_RUN_FROM_PACKAGE' to '1'. This is primarily used by Azure Functions, where we need to deploy the entire package (and there by making the wwwroot as read-only). While its very useful in Functions, you will see weird things in normal Web App (such as App_Offline not found, the wwwroot/lib folder not found, you will see older files in the FTP folder but latest ones in the Kudu console etc).

The simplest fix is to update the setting 'deploymentMethod' to 'zipDeploy' in your YAML file.