A couple of days ago, Microsoft released the engine they're using to do git deployments to Azure. I've had a task on my TODO list for a while to get that kind of functionality set up on my DEV IIS server, so I'm interested in trying out Kudu for that purpose.
The "Getting Started" document shows how to run the web front-end, but everything in there uses "http://localhost:PORTNUMBER" type URL's for git repositories, site URL's, etc.
I realize this is probably getting too far ahead of them, but I'm wondering if anyone has pointers for how to set it up using real domains on "regular" IIS instead of all of the localhost bits?
This is an old question, so I'm giving an updated answer with more current info since I just worked through setting up Kudu on an internal deployment server. The currently selected answer only deals with if you are directly running Kudu from within a development environment.
If you are deploying to a "production" type environment and don't want to install Visual Studio on the target server, there is a good guide on the project website on github.
https://github.com/projectkudu/kudu/wiki/Deploying-to-a-server
On the target server, you will need to install:
MSBuild ( http://go.microsoft.com/fwlink/?LinkId=309745 ) - comes with Visual Studio
NodeJS ( http://nodejs.org )
Git ( http://git-scm.com/downloads )
Back on your development machine, clone the git repo and build using the "build.cmd" file, following instructions in the above link.
In running build.cmd I got several test failures which blocked the build from producing artifacts. These were all related to Mercurial, which we don't use. Installing a Mercurial client didn't make them magically go away, so I disabled the tests rather than sink a bunch of time into debugging my environment.
Your build output will indicate the failures. I disabled by commenting out the [Fact] attribute.
These are the tests I disabled:
tests/Kudu.Core.Test/HgRepositoryFacts.cs (all tests)
Once you have a successful build that has created all the items in the artifacts you can move to deploying the Kudu website and web service code. The below instructions are for setting up a distinct web application instance, rather than dumping everything in c:\inetpub\wwwroot, which is how the instructions read.
Copy "artifacts\Release\KuduWeb" to the target area on the server where your website will run from. I run my kudu install with a separate host header, but you could as easily use a separate port or run as the root website. This directory will be the root for your web application.
Create an empty "App_Data" folder immediately under the KuduWeb folder.
Copy "artifacts\Release\SiteExtensions\Kudu" to the same level as the folder in step 1 and rename to "Kudu.Services.Web". This location is set as a relative path in the KuduWeb web.config file - setting serviceSitePath.
Open IIS Admin and create a website pointing to the "KuduWeb" folder from step 1.
Configure the app pool from step 4 to run as "LocalSystem". This is required to manage IIS Sites.
Create a new folder "apps" at the same level as KuduWeb. This is where deployments will be sent. Note: this location is controlled in the KuduWeb web.config file - setting "sitesPath"
Change filesystem permissions to grant "Users" full access to the "apps" folder created in the above step.
On starting my Kudu website, I got the following error.
Parser Error Message: Could not load file or assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
For some reason it didn't copy the appropriate MVC version into the deployment artifacts.
If you hit this error, the MVC 5 file can be obtained via NuGet. I found that my source code was built against 5.1.0, so this is the appropriate link:
https://www.nuget.org/packages/Microsoft.AspNet.Mvc/5.1.0
In order to extract the dll, I set up a new dummy project and used NuGet to pull down the dll via the package manager console.
Install-Package Microsoft.AspNet.Mvc -Version 5.1.0
Once you get the binary, copy it from package directory ( .\packages\Microsoft.AspNet.Mvc.5.1.0\lib\net45\System.Web.Mvc.dll ) to the website bin directory on the target machine.
At this point you are up and running. Use the web interface to create your application. It will create a subfolder under the "apps" directory with a tree that should be self explanatory. It will also have created two new websites for your application:
kudu_{your-app-name}
kudu_service_{your-app-name}
In a production situation, you should create an additional website running on appropriate port/host header that points to: .\apps\\site\wwwroot
Now you can add a git remote for your deployment. Go to your source location in a git console (ex: Git Bash) and add the remote as identified by Kudu. Note: you may need to change localhost in the url to be the appropriate server name.
git remote add deploy http://:52711/your-app-name.git
Push your code to the new "deploy" remote and see what happens. You should see all the normal push messages, plus the build output.
git push deploy master
My initial push failed to build and deploy due to "node" not being recognized. It was in the path, so a server reset convinced the path environment variable to be refreshed. You may find additional errors to work through. For instance, I had an issue with MSBuild being imported and causing a hiccup.
error MSB4019: The imported project "C:\Program Files (x86)\MSBuild\Microsoft\Visual Studio\v11.0\WebApplications\Microsoft.WebApplication.targets" was not found.
YMMV, but these are all solvable problems now. Good continuous deploying!
The project automatically sets up two websites on IIS for each application you add using the web front end. Kudu doesn't automatically map the bindings for them but it's relatively easy to open IIS and find the two sites named "kudu_appname" and "kudu_appname_service". The service website is the one that you point GIT too and the other one is the site itself. Just add public bindings to them by right-clicking and "edit bindings". You can then add public hostnames to them.
This is the easy part. The hard part that I'm still working on is getting authentication working so any random Joe isn't able to push to my kudu repository!
Related
A website with webjob not deploying to Azure.
I am having an issue getting a website with an associated webjob console application to deploy using continuous deployment via Visual Studio Online. I am using VS2013 with update 4 and latest Azure SDK.
The website, and the associated webjob, will publish to Azure using direct publish for Visual Studio and works perfectly, so I am confident the publish settings are fine.
The solution will build and work locally fine.
The solution, once checked in, will build and (seemingly) deploy fine in VSO (using CI) and Azure notes the build was successful and shows it as 'Active deployment'.
However, the website and associated webjob will not be updated.
When I have browsed the deployed files after the VSO build and deploy on Azure, all that is happening, is the binaries of the console app are being copied into the bin/ folder of the website.
None of the website files are being updated. It is almost as if it is deploying the wrong project!
If I remove the Webjob and just deploy the website, it will build and deploy fine through VSO - the website will update.
It is adding the webjob that causes some issue with the deployment via VSO.
I am confident all steps are correct to add the webjob to the WebApp, with the correct webjobs-list.json being added to the webapp and webjob-publish-settings.json to the Console app - as I said, publishing the website (with the webjob) direct to Azure works perfectly, and both the site and webjob get updated.
I have searched post after post and tried all manner of things, but none have worked.
Given the fact this published fine direct from VS, and also that the build is completing, it would suggest that something is wrong with the VSO Build Defintion.
My first guess would be to change it from building the solution to instead building the web project only, but this does not seem to work.
I have also tried every Output location setting (both for the solution build and the web project build) - the only one that works and the build completes is the solution (.sln) build with 'SingleFolder' set.
I have been battling this for a couple of days now an I'm a bit stumped!
This also happens if you have a static website being deployed using a Visual Studio solution via VSO with an automated build - unless the Visual Studio project / solution containing the website is changed then the actual site contents will not be redeployed.
I think your hunch that it's deploying the wrong project is correct. If you have multiple "deployable" projects in your solution (and the console app is considered deployable, as this is one way you can host/deploy a webjob), you need to tell Kudu which one to deploy.
You can control it adding a new setting under "app settings" on the "configure" tab for the webapp.
The setting you want is Project and it's a relative path from the solution root to the .csproj file of your web project.
Alternatively, you can specify the setting in a custom .deployment file.
Relevant Kudu documentation here
From the documentation:
You can specify the full path to the project file. Note that this is not a path to the solution file (.sln), but to the project file (.csproj/.vbproj). The reason for this is that Kudu only builds the minimal dependency tree for this project, and avoids building unrelated projects in the solution that are not needed by the web project.
Here is an example:
[config]
project = WebProject/WebProject.csproj
I have also tried every Output location setting (both for the solution build and the web project build) - the only one that works and the build completes is the solution (.sln) build with 'SingleFolder' set
That's the root case of problem.
You can't have SingleFolder as it sets the OutDir which mess up with web job packaging.
I had to introduce a wpp.targets files in each of my web app project to create the publish package to a particular path (using PackageLocation)
So, let each project have that and set the setting to AsConfigured (or Per Project) instead of SingleFolder.
See this
We're trying to figure out how to automate our website deployment. We've picked an existing project, and started playing around.
First, I used the Publish wizard from with VS2012 to create a Web Deploy Package. We then tried deploying the package as a website, through the IIS Manager, and that succeeded without a problem. We thought we were nearly there.
What was next was to learn how to run this from the command-line, so we could script it. And that's caused us no end of headaches.
We've been playing around with msdeploy.exe, and with the .cmd file that the publish wizard created, and while both methods seem to install the package as a virtual directory just fine, neither will install the package as a root website.
Browsing around on the web, I've run across this:
Web Deploy iisApp Provider
In a sync operation, the iisApp provider copies content to a folder under the destination site that you designate and marks the destination folder as an application. The iisApp provider cannot create a site. The iisApp provider will not create applications under sites that do not exist.
And
If you want to synchronize a Web site and its related configuration, use the appHostConfig provider.
At this point, we don't know beans about iisApp, or appHostConfig, or whatever. We didn't create a package that used one or the other, VS2012 did. We haven't a clue, at this point, how to convince VS2012's web publish to create an appHostConfig package, and for that matter, I don't know if we want to.
Here's the thing - whether a given website is installed as a root application or as a virtual directory is not something the developers control - it's a decision made by the implementation team. Or testing team usually installs any given website both ways, to ensure that both work.
And since IIS seems to be able to manage to install this package as a root site, there must be a way to get msdeploy to do it.
But how?
I have an Orchard CMS website deployed to Windows Azure using Git Deploy from BitBucket.
Just with my latest changes I'm getting an error when I try to deploy:
The process cannot access the file
'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\wwwroot\App_Data\Dependencies\Joel.Net.Akismet.dll'
because it is being used by another process.
Given its Azure Websites, I can't "stop the AppPool" or anything like that. I've tried stopping the site, but then I can't do a deployment with the site stopped. I'm out of ideas as to how to troubleshoot further.
Trying to update via ftp
There is no option to "restart" but I can stop and start the site, this does not work (502 web server error).
Deleting the files the the \App_Data\Dependencies folder via ftp does not work, and gets the same error.
Stopping the site and then uploading the files via ftp does work. But trying to redeploy via Git, I get a similar error:
Command: deploy.cmd Handling Basic Web Site deployment. KuduSync.NET
from:
'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\repository' to:
'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\wwwroot' Error:
The process cannot access the file
'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\wwwroot\App_Data\Dependencies\Markdown.dll'
because it is being used by another process. Copying file:
'App_Data\Dependencies\dependencies.compiled.xml' Copying file:
'App_Data\Dependencies\dependencies.xml' Copying file:
'App_Data\Dependencies\Ionic.Zip.dll' Copying file:
'App_Data\Dependencies\Joel.Net.Akismet.dll' Copying file:
'App_Data\Dependencies\Markdown.dll' An error has occurred during web
site deployment. Handling Basic Web Site deployment.
I'm sure its not just the one dll, but rather, all the dlls in the \App_Data\Dependencies folder don't get "stopped" during a Git deployment.
Trying to set up another site on Azure Websites to do the Git Deploy
I have set up another Azure site for Git to deploy the same branch of code to and this works fine.
But when I switch my domain name to the new Azure Website, my new site no longer works, but my old one can accept git deploy.
So the website with my domain name directed at it, must be getting activity causing the update to stop working. Is there a way to stop the site AND do a Git deploy?
So after removing the Dependencies folder from my repo as per #David's comments, I'm getting a new error:
Command: deploy.cmd Handling Basic Web Site deployment. KuduSync.NET
from:
'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\repository'
to: 'C:\DWASFiles\Sites[MyWebsite]\VirtualDirectory0\site\wwwroot'
Error: Access to the path 'Joel.Net.Akismet.dll' is denied. Copying
file: '.gitignore' Deleting file:
'App_Data\Dependencies\Joel.Net.Akismet.dll' An error has occurred
during web site deployment. Handling Basic Web Site deployment.
Seems like the Kudu sync is seeing that there are no files in the Dependencies folder, and trying to delete them! The same happens when I have no Dependencies folder at all - it tries to delete the Dependencies folder.
#David is there a kudu ignore file?
SOLVED!
OK I kept at it, and I have finally resolved it.
I deleted the entire app_data folder (backed it up first) then checked this into Git.
This was pushed into Azure, giving me a fresh Orchard site
I then re-added my app_data but chose to ignore the app_data/dependencies folder
pushed to Git and updated to Azure perfectly
Hope my next check in still works (fingers crossed)
I'm guessing that the root of the problem is that you are committing the App_Data\Dependencies folder into your repo. This folder is something that Orchard creates dynamically, and should not be in your repo.
I suspect that if you don't do this (by using .gitignore), everything will work fine and you won't get this error.
You can restart the website just before deployment, which is akin to recycling the app pool. Just hit the restart button from the footer on the dashboard.
Before we used TFS, we were building our packages locally using visual studio. There was a lot of projects organized into solutions. When we wanted to build the package, we simply located the ccproj project, right click on it and hit “package”.
There is couple of specific in our solution:
We use web roles with multiple web sites and virtual applications and we have them as project dependencies in VS2012 solution
We use config transformations for both web and worker roles. Worker roles transforms was achieved by adding transform target manually to the project file.
We have some additional class library projects – their outputs needs to go in a subfolder of the worker role along with correct configuration files, it is kind of plug-in architecture. We used some xcopy commands to include these non-referenced libraries in our worker roles.
Everything worked smoothly when building in VS 2012 locally.
When migrated to TFS we quickly learned that we won’t be able to replicate the same build process on build server
It turned out that TFS is not preserving solutions structure, more
details here:
http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/9ac815c8-5961-4670-a6d0-660a9b66da9c
The project dependency that was solving multiple web sites and
virtual applications in a single role did not work on build server,
probably because of different output directory. We had to add some
hacks in our ccproj and csproj files to get these published and
correctly included in the resulting package.
xcopy commands failed because of different directory structures on
TFS build sever.
We had to force run cspack on TFS build server by explicitly adding
/t:Publish parameter to msbuild command line.
Config transforms for worker roles did not worked, we had to force to
occur using another hacks in the ccproj and csporj files.
There was more issues but those are too detailed. I would keep it on
high level just to illustrate the whole issue. The build somehow
works now, but we have now a lot of hacks in place now.
I have two questions:
Is it possible to configure TFS build server to have exact same
behavior as the local build in VS2012?
Is there any official solution for building azure packages with multiple web sites and virtual applications in a single web role?
I haven't yet tried this on a TFS build server, but the approach outlined in my blog at http://michaelcollier.wordpress.com/2013/01/14/multiple-sites-in-a-web-role/ has been working well. The "trick" is basically to modify the .ccproj file to tap into the CoreBuildDependsOn target, adding logic that will execute MSBuild against the secondary sites. This should also allow config transforms to work.
Does MS Deploy support the following scenario?
Create a package from a Team Build drop
Install the web application into IIS6/7 including app pools, settings, etc.
It doesn't seem to want to let me configure IIS on the destination server if my package wasn't created from IIS originally.
If you pass the parameter DeployOnBuild set to true, then your build will produce not only your normal web site files under _PublishedWebSites, but also one whose name ends with _Package. That will contain your package, the parameters file and the manifest, plus a .cmd file for deploying the package.
What it will not contain is anything you didn't tell MSBUILD to place into the package. In particular, no, it won't contain IIS settings unless you told MSBUILD to place IIS settings there. It won't get the settings from out of the air - it will only get them from your local IIS, and only if that's where you have your project set up.
The current feature set does not support this scenario - Microsoft