David Radcliffe

Managing multiple web app configs

One of the most important things that you must do when building a web app is to keep distinct and separate configs for each environment. This is importnant because for one, your database will be different between development and production (and possibly testing and staging). You won't want to actually send emails in development, and you'll probably want to enable test mode for any payment providers or other third-party APIs. The list could go on - there are many use-cases and reasons why you should keep sepearate config. It boils down to this: you shouldn't have to worry about changing these things when you're ready to deploy or test.

This concept, and how to accoplish it, is a no brainer for Rails developers and even some PHP developers. In the .NET world this is a fiarly new concept and there hasn't been much support for anything of the sort until recently. With VisualStudio 2010 Microsoft brought us the idea of config transforms. I'm not going to go into the details but basically you have to write xml transformations to customize your main config file. That wasn't going to cut it for me so I set out to come up with a better plan. This is what I came up with.

NOTE: This is in the context of a ASP.NET MVC project.

Inside our web project we have a standard web.config file. We also have a Config folder, with a folder insie for each environment. This one has four environments, development, production, staging and test.

Inside each of these env folders are section specific config files. .NET config files support including files from another location. This means our main web.config file is pretty lean. Here's a snippet:

<appSettings configSource="Config\appsettings.config" />
<connectionStrings configSource="Config\connection_strings.config" />
<hibernate-configuration configSource="Config\nhibernate.config" />
<unity configSource="Config\unity.config" />

If you look closely, you will notice that we are not pointing these files to a specific environment. This is very important. Now we can copy the config from any of the environment folders to the root Config folder and that config will be loaded.

We took this one step further, and added rake to our toolkit. With a very short rake task we can now cleanup or change the config from the command line. All I have to do is type 'rake config' or 'rake config:production' to load the appropriate config.

desc "Build the config files for the development environment."
task :config => "config:development"

namespace :config do
  ["development", "staging", "production", "test"].each do |e|
    desc "Build the config files for the #{e} environment."
    task e.downcase.intern do
       cp_r "Web/Config/#{e}/.", 'Web/Config'
    end
  end
  
  desc "Clean out all active config files"
  task :clean do
    rm Dir.glob('Web/Config/*.config')
  end
end

We have also added this to our build scripts so that when we build locally, the dev config is automatically installed. On our build server, the appropriate configs are installed as well.