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

Publish to IIS #105

Closed
danroth27 opened this issue Apr 21, 2015 · 12 comments
Closed

Publish to IIS #105

danroth27 opened this issue Apr 21, 2015 · 12 comments
Assignees
Milestone

Comments

@danroth27
Copy link
Member

ASP.NET 5 -> Publishing and Deployment -> Publish to IIS

@guardrex
Copy link
Collaborator

@Rick-Anderson If it's worth anything, you have my posts on my little battle to work something out until the new VS tooling makes publishing to IIS with WebDeploy sweet:

Separate WebDeploy commands work
... the batch file that I'm using is below ... very simple. I call it from the PowerShell script that VS generated for my 'Publish to Filesystem' method. I use ...

& .\msdeploy.bat

inserted immediately after the Publish-AspNet ... command in the PowerShell script.

Notes on Gotchas for Publishing to IIS

Here is the script I'm using to stop the AppPool, deploy the app, restart the AppPool. I can confirm this works quite well.

@echo off

REM Uncomment the next line to setup a Gulp method (e.g, "ProcessGulpTask" is the name of the one I'm using) for processing any Gulp tasks prior to deployment to IIS
REM gulp --gulpfile c:/PATH_TO_GULPFILE_IN_PROJECT/gulpfile.js ProcessGulpTask

set iis_website=IIS_WEBSITE_NAME
set computer_name=https://CLOUD_SERVICE_ENDPOINT.cloudapp.net:WEB_DEPLOY_PORT_AZURE_ENDPOINT/msdeploy.axd
set username=VM_NAME\ADMINISTRATOR_OR_WEB_DEPLOY_ACCOUNT_USERNAME
set password=PASSWORD
set source_content_path=C:\LOCAL_PUBLISH_PATH\bin\output
set dest_content_path=SERVER_PUBLISH_PATH_(PATH_TO_FOLDER_ABOVE_THE_WWWROOT_FOLDER_ON_THE_SERVER)
echo.
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -allowUntrusted -source:recycleApp -dest:recycleApp="%iis_website%",recycleMode="StopAppPool",ComputerName="%computer_name%",UserName="%username%",Password="%password%",AuthType="Basic"
echo.
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -allowUntrusted -source:contentPath="%source_content_path%" -dest:contentPath="%dest_content_path%",ComputerName="%computer_name%",UserName="%username%",Password="%password%",AuthType="Basic"
echo.
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" -verb:sync -allowUntrusted -source:recycleApp -dest:recycleApp="%iis_website%",recycleMode="StartAppPool",ComputerName="%computer_name%",UserName="%username%",Password="%password%",AuthType="Basic"
echo.

Let me know if I can be of any assistance. I'd like to make some kind of small contribution if I can.

@danroth27
Copy link
Member Author

@sayedihashimi

@sayedihashimi
Copy link
Member

@danroth27 is there a question here for me?

@sayedihashimi
Copy link
Member

FYI we have IIS support on the backlog, but it won't make if for the initial release of VS2015. Until then you can publish to a folder using File System and then transfer to your remote server.

@guardrex
Copy link
Collaborator

It's the "transfer to your remote server" that is the pain point. My suggestion has been to trigger WebDeploy commands from a script called by the PowerShell script that you have the option for in publish to Filesystem.

Using a script there also presents a good opportunity to execute some Gulp tasks before having your WebDeploy commands deploy but after compilation is complete (e.g., HTML minification of Razor views, where you need to inject Razor directives back into gulp-minifed markup, because the Razor directives must be on their own lines in the final emitted markup).

I've been working with the script above for weeks now, and the stop-the-AppPool, deploy, start-the-AppPool sequence there works great.

Because it's WebDeploy and not XCopy, I feel it offers a great performance gain for deployment, but I haven't profiled the two methods. I realize what I'm proposing is a bit of a hack to make it work, but my staging server is an Azure VM, so I needed something that would work now. My guess is that others in a similar situation would benefit from this approach.

@guardrex
Copy link
Collaborator

guardrex commented Jul 6, 2015

@Rick-Anderson I think publishing to IIS out of VS deserves more attention than you gave the issue in your doc on the topic. I suggest this guidance be improved and cover the issues I brought up in #256. At least address my question in #317.

@Rick-Anderson
Copy link
Contributor

Thanks! I’ll schedule a review.

From: Luke Latham [mailto:[email protected]]
Sent: Sunday, July 5, 2015 9:39 PM
To: aspnet/Docs [email protected]
Cc: Rick Anderson [email protected]
Subject: Re: [Docs] Publish to IIS (#105)

@Rick-Andersonhttps://github.com/Rick-Anderson I think publishing to IIS out of VS deserves more attention than you gave the issue in your doc on the topic. I suggest this guidance be improved and cover the issues I brought up in #256#256.


Reply to this email directly or view it on GitHubhttps://github.com//issues/105#issuecomment-118710948.

@Rick-Anderson
Copy link
Contributor

@guardrex - You have some great suggestions. We're starting to remove Azure content from the docs - Azure content will live elsewhere. We also don't want the article too long or complicated. Maybe you could give me an outline of the changes you'd like to see.

@rubenprins
Copy link

@Rick-Anderson, I think the main issue that really deserves way more attention is the fact that neither MSDeploy nor XCopy will work in the wild as it is. Because ASP.NET 5 will lock files, publishing will usually end up with "file is in use" errors, unless you're publishing an application that is new or is never used. (aspnet/dnx#1068, aspnet/Hosting#141

A real issue on IIS production servers is also that simply recycling an application pool will not prevent file locks. Because when you recycle an application, the new application instance will start up immediately when a request is received. So for a production application, a recycle will immediately spawn a new ASP.NET 5 application, locking your files before you can copy them. The only way to prevent this, is by 1. outright disabling (stopping) the application pool, 2. waiting for long running requests to end, then 3. copying, and then 4. re-enabling the application pool. Which is what @guardrex's script does. (And app_offline.htm isn't supported as well, so that's no longer an option either; see aspnet/Hosting#141.)

Also note that updating an ASP.NET 5 application requires remote administration privileges to work; if your hosting setup only allows you to upload files, ASP.NET 5 will not allow you to update your application, as you cannot stop/start applications by just copying files. Also, aspnet/Configuration#98 indicates that restarting is needed for configuration changes anyway.

Next, there is no mention about requirements on the application pools. As far as I understood, since AppDomains no longer exist CoreFX, it is required that every single application has its own application pool. This needs to be called out as well.

Finally, it needs to be called out (both for IIS and Azure), that when publishing to subapplications (as in the current docs), it is an absolute requirement that the approot and webroot folders do not live in the main website's wwwroot folder. Because all files in the approot will be publicly accessible if you do, and it will not be possible to host more than one subapplication at the same level (application /A's approot will be overwritten by application /B's approot). So you need to work with virtual directories, always.

All these issues are completely new for existing ASP.NET developers, as the old ASP.NET did not have any of these limitations; but due to the architectural changes in ASP.NET 5, and lack of a proper deployment story, they must be called out and documented.

@guardrex
Copy link
Collaborator

guardrex commented Jul 6, 2015

publishing will usually end up with "file is in use" errors, unless you're publishing an application that is new or is never used

&

A real issue on IIS production servers is also that the script @guardrex suggests will not work either: simply recycling an application pool will not prevent file locks.

Yeah, well, I never said I was trying to "prevent file locks." What I'm trying to do is work around the long-standing general issue of file locks in IIS with MSDeploy and the specific case for this file lock I'm seeing over and over with .NET 5 apps in IIS. What I posted does work, and I am "in the wild." I use it daily ... as I show. Are you talking about some other file lock(s) other than the one that is usually locked, the app's DLL file? Did you actually test something like what I proposed and it didn't work before you commented?

The file locking problem is not solved by "recycling" the AppPool explicitly (i.e., recycleMode="RecycleAppPool"). What I said and what the script does is work around the issue by stopping the AppPool (i.e., recycleMode="StopAppPool"), deploying the app, then restarting the AppPool (i.e., recycleMode="StartAppPool"). Yes, it gets reccycled in the process, but it's not like it's stopped and immediately restarted. You missed a step there ... deployment. The three commands are executed sequentially; therefore, the deployment step will not occur until the AppPool has been stopped, and restarting the AppPool will not occur until the files are copied.

@sayedihashimi has stated in a general way that this is what can/should be done in any cases where file locking is preventing deployment generally:

In the case that ... your app is not getting taken offline soon enough [to prevent file locks from stopping deployment] then I suggest that you take the app offline before the publish begins. VS2013 publish Web deployment task failed The file is in use

and

There are a lot of reasons why you may want to take your app offline during publishing. For example you app has files locked which need to be updated ... Web publishing updates for app offline and usechecksum

... and similar remarks by Harsh Mittal in Taking an Application Offline before Publishing. Although Harsh is referring to using App_Offline.htm, and we all know that that won't work for this particular problem (.NET 5 apps on IIS), the guidance concept of taking the app down, deploying, putting the app back up is sound.

The only way to prevent this, is by 1. outright disabling the application pool, 2. waiting for long running requests to end, then 3. copying, and then 4. re-enabling the application pool.

Yes. That's it. I wouldn't use the phrase "outright disabling" in place of "stopping," and you write about it like somehow MSDeploy always left apps running while it was copying files to the server. I've never read or heard of it working that way and doubt that that's the way MSDeploy does things under the covers (@sayedihashimi can correct me if I'm wrong).

Everything else you mention is outside of the scope of what I'm trying to get at with the team on the docs dealing with publishing to IIS, but I guess that those are all great points and that @davidfowl heard you.

@Rick-Anderson My focus was on Azure because that's where I'm at; however, I think what I proposed there would work in a general way for any IIS installation.

Folks new to .NET 5 and IIS should probably get more in docs than "Use XCopy! ... Have a nice day." That seems especially true now that we've heard from @sayedihashimi that VS 2015 RTM isn't going to have a nice bit in place for this, and it's even a bigger deal when you run down the list of all the little "gotchas" that you have to watch out for: Things like pointing the app in IIS to the wwwroot folder but publish to the folder above it. Things like the 32-bit setting for the AppPool depending on which CLR runtime you're using. Troubleshooting advice, like how to manually add the <customErrors> section to the generated Web.config file if needed. I think all of these little bits should be in the official docs, and they pertain to IIS everywhere, Azure VM or not.

Hooking a script (such as the one I show) in the PowerShell script for publishing to the filesystem makes Web Deploy work as a one-click process, just like we knew and enjoyed in VS's earlier versions. Yeah, it's rough ... it's a hack ... and I admit I haven't tested it in anything enterprise-sized, such as what @rubenprins is handling, but it's probably a heck of a lot better than XCopy. You don't have to take a nap every time you make a tiny app change when you have MSDeploy at your service. It's been quite fast and syncs as advertised in my testing.

Thank you for letting me make the comments. @davidfowl and @shanselman are right about how well this new open source, open discussion approach is working.

@rubenprins
Copy link

@guardrex, Sorry, I missed the recycleMode="StopAppPool", so I take that point about your script back. It's still an awful hack though, that should be handled by the tooling by default, and indeed does not work for XCopy or file sync deployment at all.

We currently use a file sync job for IIS, regardless of technology (ASP Classic, ASP.NET, PHP, etc.) which works like a charm to keep all our servers in sync; ASP.NET v5 will make this a real and IMHO unnecessary pain.

@guardrex
Copy link
Collaborator

guardrex commented Jul 6, 2015

I agree. It's rough as hell. I just know I would be pulling my hair out if I didn't have some kind of MSDeploy working for me.

trobinson41 pushed a commit to trobinson41/Docs that referenced this issue May 26, 2021
…rint-update

Feature/custom vcc blueprint update
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

5 participants