Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Run From Package: a new way to deploy your Azure Web Apps and Function Apps (in Preview) #32

Closed
davidebbo opened this issue Feb 15, 2018 · 241 comments

Comments

@davidebbo
Copy link
Contributor

Please use this issue to discuss Azure/app-service-announcements#84

@Suchiman
Copy link

Sounds great!

  • Whats the performance like?
    • Are reads always deflating or is it cached in locally?
    • How does this affect local cache?
  • Is it compatible with all technologies (.NET Core, .NET Framework, etc.)?
  • What happens when you point it to a new zip file?
    • The announcement says "its atomic", is it smooth like slot swap, or
    • Is the zip downloaded, app halted, zip remounted, app restarted?
  • Is the transition to the new zip file synchronous or asynchronous?
    • If async, is there a way to detect when the transition to an updated version of the zip file is completed? (e.g., when slot swapping, the powershell cmdlets return, but requests may hit the old page for about another 30 seconds which is unfortunate for automation)

@davidebbo
Copy link
Contributor Author

davidebbo commented Feb 15, 2018

@Suchiman great questions:

  • It does some local caching
  • It shouldn't be used with the Local Cache feature (probably conflicts, untested)
  • It should in theory work with all stacks
  • The App Setting change will restart the app. So it is atomic in the sense that you can't be 'half-baked', but it is not smooth like slot. That's a potential future improvement, at least for apps that have multiple instances
  • It's the same as modifying an Azure App Setting, which is async.

@shibayan
Copy link

shibayan commented Feb 15, 2018

It's cool feature.

  • Is there a way to notify that deployment is complete?
    • Similarly, when the deployment fails?
  • Is there a limit on the size of zip file?
  • If I change App Setting while asynchronously deploying, will the deployment abort?
  • Just an idea, How about the feature to deploy from a local machine use Azure CLI?
    • Transparently upload zip to storage and deploy it to App Service

@anthonychu
Copy link
Member

Does it re-pull the zip file from the specified location on restart or scale out? Just wondering if we need to worry about the SAS URL expiring.

@devlead
Copy link

devlead commented Feb 15, 2018

@davidebbo Will/is there be an option in the kudu API to do this kind of deploy this?
Would be nice if similar to zip deploy something like post {"uri": "=https://davidebbostorage.blob.core.windows.net/content/.....D"} to /api/RunFromZip

to get a 202 or 200 if

  1. Request received
  2. Can access uri
  3. Settings changed
  4. Zip downloaded and mounted

@martinpeck
Copy link
Member

This is a great feature! Thank you!

Is there some guidance for how this changes what should be deployed for your app? For example, I'm assuming that the zip file should include the node_modules folder, right?

@securityvoid
Copy link

Is there any way to set the appropriate environmental variable from a visualstudio.com build? If so, this should be able to be automated now since you can already zip up the source.

@securityvoid
Copy link

Alternatively, can this be used with git deploy? e.g. Zip file is returned to git, auto-deploys to environment; ZIP variable points to the file path where the Zip sits in the environment?

@davidebbo
Copy link
Contributor Author

@shibayan Deploying completing is basically equivalent to the site restarting after changing an App Setting. If something goes wrong during zip download, you'll see a file called "FAILED TO DOWNLOAD ZIP FILE.txt" in wwwroot from Kudu with error details.

There is no strict size limit, but it does use the local storage, so in Free/Shared/Consumption really large zips could hit the limit.

The tooling part like Azure CLI is something that would come later and build on top of it.

@davidebbo
Copy link
Contributor Author

@anthonychu Yes, it does repull the zip each time. So:

  • Make the SAS valid as long as you want the site to work
  • Use a storage account in the same region

@davidebbo
Copy link
Contributor Author

davidebbo commented Feb 15, 2018

@devlead Note that the zip is not uploaded a part of deployment, but instead that happens at runtime. There is no deployment per se, other than setting the App Setting.

Potentially, Kudu could build the zip from a source project, and do the upload. Though that does raise some questions about it needing write access to the blob storage.

@davidebbo
Copy link
Contributor Author

@martinpeck Yes, it should absolutely include the node_module folder, and basically everything your app needs at runtime. Think of it this way: if you were to deploy via good ol' FTP, you'd copy a bunch of files. That exact same bunch of files is what you want in your zip.

@davidebbo
Copy link
Contributor Author

@securityvoid similar to previous comments. Basically, right now we just have the low level intrinsic that knows how to handle the App Setting pointing to a zip. There can be all kind of deployment workflows built on top of that to create the zip, host it and set the App Setting. I don't know VSTS well, but presumably it's flexible enough that you could be this today with enough custom build logic.

@securityvoid
Copy link

@davidebbo Thank-you for the response. I'm going to play around with this some. As long as the variable supports pointing to the local file-path there are a lot of work flows that might work here. This should be a great feature!

FYI, in case someone is looking how to set an environment variable from VSTS:
https://marketplace.visualstudio.com/items?itemName=pascalnaber.PascalNaber-Xpirit-WebAppConfiguration

@tony-gutierrez
Copy link

tony-gutierrez commented Feb 15, 2018

How would this zip contain node_modules that were built to be compatible with the environment? If I am on a mac and build a node module that uses gyp or is anything other than simple js, and deploy that zip, there is no way it is going to be compatible.

@devlead
Copy link

devlead commented Feb 15, 2018

Note that he zip is not uploaded a part of deployment

@davidebbo I get that, but just setting the setting doesn't guarantee the web app can access the zip file. If an api could provide at least some minimal validation, that would give more confidence in the deployment.

And epic if an api could "like" the zip deploy api wait and give a 2xx when web is up or error if failed, that would give immediate feedback to fail or retry from CI.

@devlead
Copy link

devlead commented Feb 15, 2018

How would this zip contain node_modules that were built to be compatible with the environment?

@tony-gutierrez Personally I would build and deploy from CI which would be using a Windows agent.

@davidebbo
Copy link
Contributor Author

@tony-gutierrez Yes, that's true. This issue also exists today if you use FTP or msdeploy. The only case where it doesn't exist is when doing Kudu git deployment, since that has a build step that restores packages.

There is also the possibility of solving this via a CI server like VSTS. In such world

  • your sources don't have the packages
  • VSTS restores them at build time and has knowledge about the target environment
  • It zips that up and all is well, without your client having to worry about it

So it may be that 'raw' Run-From-Zip' is a little too low level in some scenarios if used by itself. But the right tooling can make it work correctly (but really, this is no different from msdeploy/FTP today).

@davidebbo
Copy link
Contributor Author

@devlead yes, I think this is something that can be built on top of the low level intrinsics. In fact, you could easily write a command line tool that takes the zip, uploads it to blob, sets the URL, and hits the Web App to make sure everything works.

@Suchiman
Copy link

@davidebbo but how does hitting the web app make sure everything works? Since its async, it sounds like it would need a Thread.Sleep(30000) to approximiate when the changes took effect.

@davidebbo
Copy link
Contributor Author

@Suchiman is is no different from changing an App Setting in App Service today. You have FOO=1 and change it to FOO=2, and it can take 10 or 20 seconds before the change is live. The very same applies here.

@Suchiman
Copy link

@davidebbo Not really the answer i hoped for but i guess i can put a version.txt into the zip to workaround it and just poll it every second in the release process to block until the new release is live.

@securityvoid
Copy link

@Suchiman Why not simply return the environmental variable that points to the zip? If its the new value, you know the new release is in place. Then you don't need anything specifically in the release.

@Suchiman
Copy link

@securityvoid mh interesting trick, cool yeah that should work, thanks 👍

@davidebbo
Copy link
Contributor Author

@securityvoid @Suchiman one small twist is that if you have multiple instances, they will not necessarily all big ready at the exact same time. So you might still want to wait a few seconds even if one instance tells you it's ready.

@dfinke
Copy link

dfinke commented Feb 16, 2018

The deploy worked. I can seen the function in the function apps blade. When I click on the function, get the error below. I deployed a PowerShell run.ps1

image

@davidebbo
Copy link
Contributor Author

@dfinke Yep, that's a known issue in the Functions Runtime (not in this new feature) that just got fixed. Until the fix is deployed, just make sure to include a host.json at the root of your zip. It should just contain {}

@dfinke
Copy link

dfinke commented Feb 16, 2018

@davidebbo Thanks, yup, I just included it, was coming back to delete my comment and saw your response. This is pretty sweet and will simply function app DevOps.

@xt0rted
Copy link

xt0rted commented Mar 12, 2019

I've been having issues on one of my sites as well. Same setup, zip push/run from package coming from AppVeyor.

It looks as if the site's not being warmed up before swapping because when I hit the site after a deploy it takes forever to respond and then I usually get a 500 error. After restarting the site it starts up pretty quickly and is fine until the next deploy.

This all seemed to start after I migrated the site to .net core on February 17th. Prior to that I didn't have any issues.

@PaitoAnderson
Copy link

@xt0rted That is exactly my issue, thanks for sharing! It does seem like a timing issue where it doesn't wait long enough before starting up.

@JasonFreeberg
Copy link

JasonFreeberg commented Mar 12, 2019

Hi @PaitoAnderson and @xt0rted, could you please email me with your site names? I'm trying to repro your issue. Thanks!

@williamthiago
Copy link

Today I use a .deployment file to set a target other then wwwroot so I can have two applications on the same webapp instance (API + web).

[config]
SCM_TARGET_PATH=../api

Does RUN FROM PACKAGE uses the .deployment file or it's restricted to the wwwroot destination?

@thecontrarycat
Copy link

thecontrarycat commented Apr 1, 2019

@JasonFreeberg We're also seeing weird issues with Run From Package when auto-scale scales up a busy site. Today we were brought completely offline with the site moaning about precompilation:

The file '/Account/Login.aspx' has not been pre-compiled, and cannot be requested.
   at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
   at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
   at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp)
   at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
   at System.Web.UI.PageHandlerFactory.GetHandler(HttpContext context, String requestType, String virtualPath, String path)
   at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0()
   at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
   at System.Web.HttpApplication.StepInvoker.<>c__DisplayClass4_0.<Invoke>b__0()
   at Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
   at System.Web.HttpApplication.<>c__DisplayClass284_0.<OnExecuteRequestStep>b__0(Action nextStepAction)
   at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

It looks like the app service can't load the precompiled assemblies even though they look to be there when you view through kudu and everything worked perfectly for 3 days prior to this with no new deployment happening. Happy to work with you offline to fix as Azure support have not been much help.

@Shawson
Copy link

Shawson commented Apr 1, 2019

@thecontrarycat @JasonFreeberg We also saw some issues with this on the weekend with our Asia site- it scales twice a day, at the start and the end of the "busy" period- but while scaling up last Sunday our site became unavailable- we had to scale it up and down again to get it to come back in.

@JasonFreeberg
Copy link

JasonFreeberg commented Apr 1, 2019

Hi everyone (@thecontrarycat, @Shawson)

We are rolling out a fix for this. It will be deployed to all regions by 4/4. Please reply to this thread if the issue is still happening on or after April 5th. Thank you!

@carbonrobot
Copy link

carbonrobot commented Apr 2, 2019

I'm trying to use this new deployment method from a pipeline, but it kills the app.

After deployment, the WEBSITE_RUN_FROM_PACKAGE is set to 1 and the app returns 500
After the deployment, if I manually change that setting in Azure to 0, the website returns 200 OK, but shows an older version of the code. Quite odd.

The logs are completely unhelpful.

@thecontrarycat
Copy link

Do you have WEBSITE_LOCAL_CACHE_OPTION set to Always? You need to remove that setting for run from package to work.

@carbonrobot
Copy link

@thecontrarycat no, i do not have that option set

@Shawson
Copy link

Shawson commented Apr 3, 2019

@carbonrobot If you turn on the live log stream in Azure, do you get any more details on the 500 error?

@ghost
Copy link

ghost commented Apr 5, 2019

Hi everyone (@thecontrarycat, @Shawson)

We are rolling out a fix for this. It will be deployed to all regions by 4/4. Please reply to this thread if the issue is still happening on or after April 5th. Thank you!

@JasonFreeberg Did this happen? We are still getting the issue. It seems to be related to having precompilation enabled during deployment. App crash or Autoscale during busy periods gives "blah.cshtml' has not been pre-compiled, and cannot be requested" errors and completely takes the site down until restart.

@Kunigaikstis
Copy link

Still getting a 500 after a website is deployed.
Furthermore, how do you disable this feature for DevOps build pipelines using YAML?

@ustun
Copy link

ustun commented Sep 26, 2019

One issue we ran into was that when using Azure Devops action for deploying, we had some post-deployment scripts, however for some reason, there is nothing in the wwwroot folder except a hostingstart.html.

I thought it would take a while for the folder to be mounted, so I put some sleeps, but after about 30 seconds, there was still only that single hostingstart.html file.

Also, the docs say this feature is for function apps and only Windows, however we are using it for Linux Web Apps and it seems to work, so they need to be updated I believe.

@mslot
Copy link

mslot commented Nov 13, 2019

Does the folder where the zip file reside gets cleaned up by Kudu, or does it grow and grow? Could i potentially end up with a folder that exceeds the diskspacea available?

@JasonFreeberg
Copy link

JasonFreeberg commented Nov 14, 2019

@mslot - The home/data/SitePackages directory is treated like any other directory. The directory does not have any special restrictions on file counts or size. If the directory grows it will consume your storage, like any other directory.

@paulbatum
Copy link
Member

@JasonFreeberg I'm not sure that is correct - App Service has limits on the size of application storage. See the "storage" line in this table.

@mslot
Copy link

mslot commented Nov 15, 2019

@mslot - The home/data/SitePackages directory is treated like any other directory. The directory does not have any special restrictions on file counts or size. If the directory grows it will consume your storage, like any other directory.

So basically we have to make some kind of job that empty the zip folder, so it doesnt grow so large that a deployment fails because of no storage. We have standard plan, and I think it implies 50 gb of storage. Over time this will break deployments, because of storage gets filled.
Is there any recommended way of empty the deploy folder? Or do we need to invent this our self?

@jonarmstrong
Copy link

Has anyone else had issues where their site doesn't come online cleanly after routine maintenance when using WEBSITE_RUN_FROM_PACKAGE? I ran the site diagnostic tool and it gave me the following messages. After I got looking to the app, even simple static page requests were returning 500 errors which persisted until I rebooted the app. The note about the 'file server' suggests using the local cache option, which I think is incompatible with WEBSITE_RUN_FROM_PACKAGE.

  • Around 11/23/2019 7:12:34 AM (UTC), on Instance RD501AC56DB748, your application was recycled as the Azure scale unit was undergoing an upgrade.
  • Your application was recycled due to a file server upgrade. This event occurred multiple times during the day across multiple instances

@mattwoberts
Copy link

@ jonarmstrong Correct - the local cache is imcompatible with this - see: projectkudu/kudu#2955

I'm at this point now, and I'm not sure how best to proceed, I've been running local cache for years, but it seems if I want to deploy via azure pipelines (which in turn uses zip deploy / run from package) then I need to turn this off 🤔

@jonarmstrong
Copy link

Hi @PaitoAnderson and @xt0rted, could you please email me with your site names? I'm trying to repro your issue. Thanks!

This is a follow-up to my post on 11/23/2019. I've since dug a little deeper and realize I have the same problem was impacting @PaitoAnderson & @xt0rted. My apps are also using the WEBSITE_RUN_FROM_PACKAGE setting, which seems to be the root cause of this issue.

@JasonFreeberg Was there every a resolution to this? I have three apps which currently have bad instances because of this exact issue. The only way to resolve the issue is to restart the app and hope it comes back up. It has been plaguing my app reliability for months now. Below are stack traces from 2 of the 3 failing web sites

Instance - RD501AC561D51E

/subscriptions/3a2f_______________3e76/resourceGroups/fsp___________rg/providers/Microsoft.Web/sites/merch__________________-mahzuanneuqrm

@ 2020-02-16T09:48:18

Application: *******************.exe
CoreCLR Version: 4.6.28207.3
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileLoadException: Could not load file or assembly 'Microsoft.AspNetCore.Authentication.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. An assertion failure has occurred. (Exception from HRESULT: 0x8007029C)
   at Microsoft.Extensions.DependencyInjection.AuthenticationCoreServiceCollectionExtensions.AddAuthenticationCore(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.WebHostBuilderIISExtensions.<>c__DisplayClass5_1.<UseIISIntegration>b__0(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at ******************.Program.Main(String[] args) in d:\a\1\s\****************\Program.cs:line 17

Instance - RD501AC56B00BE

/subscriptions/3a2f______________3e76/resourceGroups/fsp_________________rg/providers/Microsoft.Web/sites/hosted_____________-bqxfcgnuocrvw

@ 2020-02-16T07:20:21

Application: ***********************.exe
   CoreCLR Version: 4.6.28207.3
   Description: The process was terminated due to an unhandled exception.
   Exception Info: System.IO.FileLoadException: Could not load file or assembly 'System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. An assertion failure has occurred. (Exception from HRESULT: 0x8007029C)
      at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
      at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, ITransportFactory transportFactory, ILoggerFactory loggerFactory)
   --- End of stack trace from previous location where exception was thrown ---
      at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
      at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
      at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
      at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
      at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureServer()
      at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
      at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken)
      at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage)
      at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
      at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
      at ***********************.Program.Main(String[] args) in d:\a\2\s\***********************\***********************\Program.cs:line 24

@katiep23
Copy link

@jonarmstrong Did you ever figure out a solution or get any help? I'm having same issue with the assertion failure error as well.

@jonarmstrong
Copy link

@katiep23 Regretfully, I've yet to receive any feedback or support about this particular issue.

@ttrushin
Copy link

I know this issue is closed, but its 2022 and we are facing this exact issue with seemingly random FileLoadExceptions that require manually restarting the app. Did anyone ever figure out a solution that doesn’t require manual intervention?

@paulbatum
Copy link
Member

@ttrushin I recommend filing a ticket through Azure support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests