I regularly install a product (Atlassian Confluence, which is Tomcat + a few files) on my server. For each upgrade, after unpacking the tar.gz, I need to change the following files:

  • conf/server.xml -> Add JNDI declarations and change port
  • confluence/WEB-INF/classes/confluence-init.properties -> Change one property
  • confluence/WEB-INF/web.xml -> Require HTTPS
  • confluence/WEB-INF/classes/log4j.properties -> Change log level
  • Move activation.jar and mail.jar from confluence/WEB-INF/libs to lib/
  • Add postgres.jar to lib/

Is there a canonical way to perform this configuration?

  • Any way to perform an "overlay" to a directory?
  • I've tried git, but git isn't good at moving files.
  • I've tried writing a script, but it cannot be contained in 1 file, since I need to have patch files. If we're going this way, is there a way to write a bash script which contains the patches, so it's self-contained?
  • Do all sysadmins just write an ad-hoc script every time, using 'patch' and 'move' to edit the files? Isn't there a better tool?

Thank you

  • 1
    why don't you look into configuration management tools like puppet, chef, ansible? – Danila Ladner Jan 25 '14 at 13:27

Configuration management tools like puppet. chef, ansible etc are the tools of choice for the modern sysadmin.

  • Is it possible to go into a little detail on each and explain pros/cons? For example, is there a reason to choose puppet over chef? – jlehtinen Jan 25 '14 at 14:22
  • @jlehtinen: I have no idea I use puppet it works for me. – user9517 Jan 25 '14 at 14:35
  • Isn't puppet a bit overkill for that purpose? It looks like it's a lot of configuration for a few files, so is it really? – Adrien Jan 25 '14 at 15:46
  • @Adrien: Start with just a dew files then move onwards after all we're all sysadmins here aren't we ? You need to decide what's correct for you just like I did and lots of other people have. – user9517 Jan 25 '14 at 16:24

Create an Ansible playbook for installing the tar and subsequent customization. Then run the playbook against the target host.

Ansible provides easy to use modules for modifying file content, copying files around, creating new files from templates, managing services etc.

Personally I've used it to modify e.g. Tomcat configuration files.

See http://docs.ansible.com/playbooks_intro.html.


I put my configuration files in a Mercurial repository (Git would also do) and I replace the original config files by symlinks to these files. This way I don't have to move them. I use a small shell script to maintain the symlinks, so that after an upgrade, I just have to re-run this script.

Let me give an example. Let's say I want to make changes to Tomcat's server.xml.

One time setup

First, I copy the original server.xml to my Mercurial config repository. Then in my shell script, I add these commands to delete the original server.xml and replace it by a symlink to the file inside the repository, e.g.:

# The location of my Mercurial config repository

rm -f /etc/tomcat7/server.xml
ln -s $CONFIG/tomcat/server.xml /etc/tomcat7/server.xml

Next I run the script for the first time, to test it and create the symlinks. I call the script setupLinks.sh and it lives in the root of my Mercurial repository.

sudo /home/admin/config/setupLinks.sh

After an upgrade

After an upgrade, I just need to re-run setupLinks.sh to replace any symlink that was overwritten. That's it.

I find it very usefull to have my config files inside a source code repository. This way I can track changes and pull new config from an upstream repository. I use named branches for environment-specific config, e.g. I have a dev branch and a prod branch.

I did not say anything about moving jar files around, but it could be done easily by adding a few lines to the shell script. You can also create symlinks to jar files.


Use the dist-trick

To avoid overwrting your config files you can use the "dist-trick": Use *.dist files (e.g. config.xml.dist) as default configuration files in your distribution. "dist" stands for distribution file. Then copy this .dist file to an non-dist file (config.xml) which is not part of the distribution. And voilà, your config file get's never overwritten again. This works very well e.g. when using git, ftp, scp or any other mechanisms to bring files to a production machine.

The dist-trick helps to avoid re-setting up or restoring things after deploying files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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