Skip to content

Servers in your checkout?

Here’s a little tip to everyone who wants to put their app server into version control – don’t do it. I’ve been recently working on an application site that does this, and it’s indescribably poor configuration control.

As well as giving each developer an easy way to get an app server setup on his or her development machine, you can see an additional motivational procedure;

  1. Build application war
  2. Put application war into the version controlled ${appserver}/deploy directory
  3. Commit ${appserver}/deploy directory changes
  4. On target server, checkout or update the ${appserver} directory
  5. Restart and viola! We’re running in production, or whatever target environment we like.

However, this procedure, while on the surface might be appealing, is under the cold harsh light of the world of production deployment, full of conceptual gaps and should not be trusted, for a number of reasons.

It’s enormously wasteful of version control resources.

First, the entire appserver is checked into version control, even though maybe onloy 10% of it (being generous) might actually change from a vanilla installation of the product.

It doesn’t control the configuration properly across target environments.

Given a configuration file, let’s say a server.xml, a hibernate.cfg.xml, or a projectname.properties, typically needs to be different in each of the development, uat and production environments, how do you capture that information? Do you want a different branch per environment? What about each individual developer’s installation? (See above re: wasteful of resources).

It just results in configuration that’s outside of version control.

Under this sort of scheme, what we end up with in the version control repository, is a ‘base’ configuration, hopefully containing the production environment’s configuration. And then sitting out there in each environment, on each developer’s machine and in the uat and other pre-production environments, is a bunch of local, uncontrolled changes to that base configuration.

Even worse, an attempt to update the base configuration may result in difficult to recover conflicts when the updated artifacts are attempted to merge with the uncontrolled local changes.

What should be done instead?

First, you should always assume you’re operating off some base version of your app server. This is a version that can be downloaded and installed according the specific instructions of that app server (hopefully, just by unzipping it or untarring it into the target directory). This is not something that would normally be in version control, unless you have a simple infrastructure style project where you put the app server’s install archive, for posterity’s sake.

Second, what should be in version control, is a series of configuration files, and scripts that install them or modify them then install them for a particular environment.

A minimal deployment process, might look like the following:

  1. Install vanilla appserver
  2. Run configuration build, of which the artifact is a series of patches to be applied onto the vanilla appserver installation
  3. Patch vanilla appserver to required custom configuration

Now, that’s not a definitive answer! It’s just the skeleton of the simplest solution I have for this situation.

For example, you might patch an already installed server, or take your patches and build a custom installation process for the whole server. Perhaps your configuration build results in an RPM or DEB file that installs all or part of the customised app server. Maybe you build a VM image which is installed and run in a VM host environment. Any of this may or may not include the application components (the war) for deployment. Different target environments might be handled by different branches, subdirectories, file extensions, or by variable expansions. “Patching” might mean manually copying new versions of the required files over the top of the vanilla ones. You might have to prompt an operator to enter production passwords because you don’t want to store these inside your configuration or build scripts.

All of these options should be considered in the context of your individual circumstance. But what you should not do, is conflate the application server install with the customised configuration control and check it into your version control system as one big blob of ugly.