How should I handle deploying web applications to multiple servers?


I have a dev, test and prod environment. No build server is available. Developers can't deploy to prod. The people that do deploy to prod copy files from test to prod. They don't have VS installed.


The way it's handled is using web.config transform. However, to deploy to prod involves putting prod code on the test server where it's copied over.


Sometimes simple mistakes are made, such as forgetting to change test back to the right environment after deployment. Or the test config gets moved to prod instead of the prod config.


So the question is, what is the best way to prevent mistakes from happening?

My first thought is let the app determine which server it's on at runtime and use the appropriate settings/connection strings/etc... However, the server names could change in the not too distant future. So if multiple apps are hard coded, that would mean updating all of them. The easiest way to handle that situation would be to place a DLL in the GAC that determines the environment.

Are there any drawbacks or possible complications that this would cause? Or is there a better solution to the problem than this?

  • Any issue with setting an environment variable on the server which could serve as a signal to the application which environment it's running in?
    – Tombatron
    Aug 2, 2013 at 0:35
  • I've never used environment variables before. I will do some research and see if that will work.
    – JayGee
    Aug 2, 2013 at 1:23
  • 1
    possible duplicate of Describe the best deployment environment you've worked with
    – ozz
    Aug 2, 2013 at 10:45

3 Answers 3


Normally the higher the deployment process is automated, the lower risk there will be. To achieve better automation, i think command line procedures (with different modes, for example, interactive v.s. quiet mode) could be a good option:

  1. I believe you won't have many environments (DEV/QA/UAT/PROD/etc.) and they are already fixed. So a fixed xslt transformation could be defined and included in your project, for example, call it web.config.xslt, in which, a list of configuration sections per environment could be defined (or a switch-case conditional configuration)

  2. use MSBuild to build the solution, and output the built files to a newwork location (preferably accessible to all developers), and at the end, transform web.config based on web.config.xslt and produce a couple of config files: web.Dev.config, web.QA.config, web.UAT.config and web.Prod.config

  3. give an option at the command line, say which environment the user wants to deploy, then batch copy all the files to the desired server (of course, you have to allow these folders shared and accessible to the deployer) and at the end copy the corresponding web.[ENV].config file as web.config to destination folder

  4. other bit and pieces (such as versioning, DLL signing and etc.) could also be included and automated through out the MSBuild process.

all these steps could be stored in a predefined solution level file, let's say it mySolution.BuildRelease.proj (all up to you) and set MSbuild (or your self-defined bat file, which calls MSBuild and your own console app) as the default app to open it.

of course, if some of the processes could not be done using command line, you might want to try write a console application and call it during MSBuild.

if you are fancy with interactive approaches, you may also define a html app (hta) to wrap up the process


In a past life I managed a group faced with this issue.

We chose to manually set the config files as needed (i.e., a code promotion from test to production would explicitly exclude the web.config file). Like you, it was a different group that did the promoting.

One major advantage we saw was that "what you saw on Test was what you'd get on Prod". If your code has ANY environment-dependent code in it, you're in trouble because you're putting untested code into production.

We learned this the hard way when a dev put if (servername != "prodServer") in the code. All was fine until the server group renamed prodServer to prodServer2 and all our connection strings, etc. switched back to their dev environment settings. That was a tough day -- difficult to explain to the business why their production system crashed so thoroughly.

tl; dr

  • Your code should never know which environment (dev/test/production) it's in.
  • Config files are not code and should never be promoted.
  • Keep your code promotion process as simple as possible. I think we used Robocopy. Setting it up to copy everything except web.config from dirA to dirB is pretty foolproof.

I know it's one of your constraints, but I'd honestly push as hard as you can to get a build server. Really.

Now I've got that off my chest, if one isn't available in the short term, potentially each environment could have its own settings repository that it looks to for server names, connection strings etc, so that a config or machine name change doesn't require physical files to change, but your admin staff (or who ever has responsibility) can change the settings in one place. Obviously each app contacts the repository via web services / wcf or whatever you fancy to get the settings. The app therefore only needs to know the location of the repository, and everything else is controlled by the admins.

Ultimately the way to get rid of manual mistakes from happening is to automate them, as you've said.

  • I had a build server at my previous place. Really miss it. I do plan to try for a build server, but it's already been shot down once before.
    – JayGee
    Aug 2, 2013 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.