Continuous deployment in .NET using Project Kudu and git
Project Kudu is a great open-source initiative for enabling git deployments of websites. That is, you can push your source code or binaries to git as means of deployment. If it's the sources you pushed, Kudu will compile them and run tests and will only deploy if successful. This is like Heroku, AppHarbor and Azure websites handle deployments, only you can have it in your own web server. Actually, Project Kudu is what powers Azure Websites deployments.
As of why you'd want that, check out this article as an example. Or Google "Continuous Deployment".
I gave Project Kudu a spin a couple of months ago, but wasn't able to get it working properly then. I gave it another go tonight with great success, using the following steps:
- Clone the git repo, and make sure you have IIS 7, node.js 0.8x, git and Mercurial installed (latter is not mandatory I think, but it is being used in some places). You will also need them installed on the server - make sure node and git are available from the PATH on both your machine and the server.
- Open in Visual Studio as Admin. I have VS 2012 and I'm running on Windows 7. I had to do
nuget restore
manually from the project root folder to get it compile all the way (stupid Nuget 2.7). - Here I got some post-compilation errors relating to node components. I solved them by executing
Setup\KuduDevSetup.cmd
andKudu.Services.Web\updateNodeModules.cmd
manually from PowerShell as admin. You need to have npm in your PATH. - Rebuild solution - now it should complete with no errors.
- The Kudu project has 2 parts, and you will need both of them on your webserver. My favorite way of deploying websites is using the Publish tool of Visual Studio. The Kudu.Web project you can just Publish to a local folder and upload to the server, but the artifacts of Kudu.Services.Web you have to take from the bin folder as it needs the exe and some other things there which are not being copied on Publish. I actually published it and then copied the bin folder over (compiled as Release).
- Follow the steps here and here to complete installation and create a new application (most you've already done if you got here).
- Creating a new application from Kudu's web interface will create 2 IIS websites, one for the actual website and the other for a service that also functions as a git repository you can push to. The two websites are on random ports. You will need to open TCP access to them in your Windows Firewall.
Overall the experience is great. This is how a deployment process looks like, pushing binaries to a remote git repository on my web server:
Project Kudu is really great, you should check it out!
Pain points
Probably because Project Kudu is an Azure Websites thing, it is being built with only that use case in mind. There are some places where it shows, and I really hope the dev team will take some time making it a good fit for general use.
Security
Both the web interface for managing applications deployed with Kudu, its background service that has some sort of a monitoring UI, and the backing service for every website deployed with Kudu - all are entirely exposed to the web. It will greatly help if they could allow for authentication.
There may be a way to use IIS to control access to those websites (HTTP auth, or using Windows credentials which I'd rather avoid), but I haven't looked into it yet. It's just too much setup to take care of, and would be nice to have that supported OOTB.
Ports management
The 2 main websites (Kudu.Web and Kudu.Services.Web) are a one time configuration, and are easy to configure under kudu.mydomain.com or something using standard 80/81 ports so no extra configuration is required.
However, every new website you create involves creating 2 new websites in IIS - one is kudu_mysite and the other kudu_mysite_service. Both are created on 2 random ports, which means you have to add rules to your firewall. Annoying.
The way I work now is this. After creating a new website using Kudu I just change the bindings of kudu_mysite to use the standard 80 port and the domain name or subdomain I have for it. The service website I push to using git and then stop, at least until I have enabled authentication for it. But that still means I have to open that port for the service on my firewall.
It would be great if Kudu would have one service for managing all websites, so there is only one port to be opened. Also, when creating a new website, allow me to set the bindings myself, in case I do want to use port 80 with some custom domain configurations.
There may be a better solution for both issues, using a proxy service or something, would love to hear about it if you got it working.
Automated installation process
Someone said WebPI?