Dolphin Deploy: Deploying ASP.net applications using IronRuby

Over the years I’ve found that build and deployment is one the most important, yet often overlooked aspects of software development. While NAnt\MSBuild has given the .Net platform automated builds, it’s XML based. People then took this approach and applied it to deploying ASP.net applications. 

I find this really interesting. If you speak to any developer about XML configuration they will run to the hills – yet it’s OK for build\deployment? Without a reliable and flexible way to deploy, the entire development line is blocked and the team will struggle to push new features out.

A while ago, I gave some support to Derick Bailey with albacore to help solve the “build” problem. I then wanted to look at the deployment problem. Having perviously manage near 200 line XML deployment files I could relate directly to the problem. I’ve found it near impossible to change settings or configure new servers when the script is that long and complex. There must be a better way. 

After playing around with some different approaches I’ve created a prototype called Dolphin Deploy (based on the Albacore name) available on github at http://www.github.com/benhall/DolphinDeploy. A simple, yet complete, example of how to deploy an MVC application is at http://github.com/BenHall/DolphinDeployExample.

Dolphin Deploy

Dolphin Deploy is a DSL for defining your deployment scripts.

The aim is to allow you to configure multiple different environments with different servers to deployment ASP.net applications. By supporting different servers in each environment, you can easily configure additional load balanced servers and have flexibility in terms of the file system structure which was one of the key issues we faced with XML.  

For example, below is a very simple script which will deploy an ASP.net MVC application, zipped in a file called MvcExample1.zip in the directory example.

environment do 
  desc “Example MVC Deployment”
  configured_as :mvc
  env :live do
    name “MvcExample1″
    host “MvcExample1.com”
    deploy File.join(Dir.pwd, “/example/MvcExample1.zip”)
    to “webserver0001″, “C:/inetpub/wwwroot/MvcExample1/”, “127.0.0.1″
  end
end

This will deploy the website into C:\inetpub\wwwroot\MvcExample1\, automatically tagging it with a release number to support rollback scenarios. The final directory would be C:\inetpub\wwwroot\MvcExample1\MvcExample1-01, incrementing the tag for each deployment. If you need to rollback, you simply point IIS back to the previous directory – at some point this will be automated. Within IIS, the site will be called MvcExample1 and have the host header MvcExample1.com.

In terms of support, Dolphin Deploy works with both IIS6 and IIS7. The script will detect the version of the server being deployed to and use the implementation appropriate. At the heart of this implementation is IronRuby.

IronRuby

The reason for using IronRuby is very simple. It wouldn’t have been possible to have the dynamic nature of Ruby, combined with interacting with IIS without it. IronRuby allows Dolphin to interact with IIS via existing C# libraries such as DirectoryServices and Microsoft.Web.Administration. By not re-inventing the wheel I was able to iterate more quickly on the important aspects, such as the DSL. While it still needs work, I think it has potential.

The DSL is executed at runtime by IronRuby. This allows Ruby methods, such as File.join and Dir.pwd, to be used directly in the configuration file allowing for more flexibility that allows for more complex examples as shown below. 

Below specifies two environments, local which has a single server while test with two servers which need deploying to. 

Both have a list of subdomains which need to be configured, instead of duplicating the list we can have it as a variable. Within the after block, we can loop around each of the items and call the method extra_header to assign the additional host header on a particular port (9999). 

In a similar way, we can call the method virtual_directory to create a virtual directory, or shell out to the cmd and write to Deployment.txt file.
headers = ['subdomain1', 'subdomain2', 'subdomain3']

environment do 
  desc “Example MVC Deployment”
  configured_as :mvc    

  env :local do
    name “MvcExample1″
    host “MvcExample1.local”
    deploy File.join(Dir.pwd, “/example/MvcExample1.zip”)
    to “localhost”, “C:/inetpub/wwwroot/MvcExample1/”, “127.0.0.1″  
    after do
      headers.each {|entry| extra_header(“9999:#{entry}.local.header”)}   
      virtual_directory “Test”, “Content”  
    end
  end

  env :test do
    name “MvcExample1″
    host “MvcExample1.test”
    deploy File.join(Dir.pwd, “/example/MvcExample1.zip”)
    to “testserver0001″, “C:/inetpub/wwwroot/MvcExample1/”, “127.0.0.1″
    to “testserver0002″, “D:/apps/MvcExample1/”, “127.0.0.1″ 
    after do
      headers.each {|entry| extra_header(“9999:#{entry}.test.header”)}   
      virtual_directory “Test”, “Content”  
      cmd “echo Hello World ” + Time.now.to_s + ” >> C:/temp/deployment.txt”
    end
  end
end

To execute and use the framework, you simple need to download the gem and reference a rake task.

The gem is available from http://rubygems.org/gems/dolphindeploy. Within your rake file, require ‘dolphindeploy’ and require ‘dolphindeploy_rake’, this will then give you the additional tasks.

The syntax, executed via IronRuby, is:

ir -S rake dolphin:deploy[env,server]

For example to deploy to the test environment for server testserver0001, you would need to execute:

ir -S rake dolphin:deploy[test,testserver0001] 

The only thing it expects is that the deploy.conf containing the DSL script above will be in the same directory as your rakefile.

The project includes other functionality, such as dynamically adding sections to the DSL to perform custom tasks, or deleting old builds. Until I document this functionality via blog posts, the best place to look would be the specs.

A minor comment, at the moment the script needs to be executed on the server itself (SSH \ Powershell for example). You also need to be administrator (and have evaluted permissions on Windows 7). After all, this is a prototype, so please don’t use it on production until it’s had a little bit more testing :) 

If you would like to help, please, please do! Grab me on Twitter while the code is available at http://github.com/BenHall/DolphinDeploy

 

About benhall

Ben Hall is a UK C# developer\tester with a strong passion for software development and loves writing code. Ben enjoys exploring different ways of testing software, including both manual and automated testing, focusing on the best ways to test different types of applications. He also loves developing web applications using ASP.net and Ruby on Rails. Ben is an ASP.net MVP and can be contacted by emailing Blog {at} Ben Hall .me .uk
This entry was posted in Albacore, DolphinDeploy, ironruby. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://aspdotnetcodebook.blogspot.com santosh

    Thanks for this cool story :)

  • http://www.chiflat-iron.com chi hair straighteners

    included. As long as a healthy balance in maintained in his life, why not allow him to explore and shine?

  • Mike

    It certainly looks good, but I don’t think there was a problem to solve to begin with. VS2010 does a great job of deploying, and rollback on the server is not as simple as pointing to a different root (think about the db schema, uploaded files etc).

    Also in VS2010 the beauty of web.config transforms is that you only transform what you want to be different, so it’s seldom 100s of lines of XML.

    And last but not least, if XML is a ‘ problem’ then how is Ruby not a problem. I can’t read Ruby, and none of my team can…

  • fschwiet

    PSake is pretty good too, for .Net build and deployment. Its inspired by Rake, but uses powershell as the script language instead of Ruby. The build/deploy tasks can be coded to do anything Powershell can do, including IIS config.

  • http://hwiechers.blogspot.com hwiechers@gmail.com

    How does this approve compare to using the Web Deployment stuff in IIS and VS2010 (http://vishaljoshi.blogspot.com/2009/09/overview-post-for-web-deployment-in-vs.html)? At first glance, it looks like Web Deploy does a lot more and is a more ‘standard’ approach.