UsingModEnvToSimplifyMultisite

I've been meaning to write this down for ages, but only just got round to it. For better or for worse, here's how I handle the simple case where you have two servers that you want to run off the same installation. This is a typical case where you have a test server and a production server, and want to be able to flexibly switch the code these run from.

I was debating making this a FAQ, but as I have never described it, no one-has ever asked a question on it......

Comments welcome (especially those of the "oh my god that is so inefficient here's how to do it better" ilk). Is it worth adding this to supplementary documentation?

Using Apache mod_env to support shared-source installations

Prerequisites: you should have installed Foswiki at least once; you should know what LocalSite.cfg and LocalLib.cfg are and what they are for; you should know what an environment variable is; you need to know what configuration management is and roughly what the subversion configuration management tool does.

Sometimes you want to be able to share the same Foswiki configuration between different sites, without having to create local custom configuration files. A typical example of this is where you want to create a test server for your Foswiki installation. Each time you upgrade Foswiki, install a new extension, or make any other change to the configuration, you want to be able to test those changes before making them "live". The problem is that the "test" server and the "live" server have different configuration requirements (different file paths, different host name, etc), but at the same time you want to minimise the differences between the files in the two installations.

Good practice also means that you should be able to revert your server to a "known good" state at any time. That means you want to keep a copy of the installation in a pristine, tested state. A good way to do this is to use configuration management tool to record the state of your installation.

So, what we want to be able to do is to have the installation recorded under configuration management, and two different servers both running using the files same stored in that configuration management system without having any custom files for individual servers.

The simple strategy described here uses the Apache configuration to customise the configuration as lightly as possible. In fact we find that just three environment variables are all that is necessary.

First off, base requirements:
  1. You need to have mod_env enabled in Apache. This is a base module since Apache 2.0, so it's probably already there. The directive you need is SetEnv.
  2. You need a configuration management tool. For the purposes of this description we'll assume Subversion, running on a local svn server at http://mysvnserver, though you can easily adapt the instructions to use your favourite CM system.

Now, let's say your two servers are configured as follows:
  • Test server
    • http://testwiki
    • files are in /home/boy/foswiki
  • Live server
    • http://wiki
    • files are in /opt/foswiki

These servers can be on the same machine, or different machines, it's up to you. We'll start by setting up the test server.

Setting up the test server

Put a Foswiki release under configuration management

First download the Foswiki release you are going to be using, and unpack it. We'll assume you've done that and unpacked it to /home/boy/Foswiki-1.2.0.

Now add this release to subversion. For example:
$ svn import /home/boy/Foswiki-1.2.0 http://mysvnserver/trunk/Foswiki-1.2.0
Once it is imported, check it out to /home/boy/foswiki:
$ cd /home/boy/foswiki
$ svn co http://mysvnserver/trunk/Foswiki-1.2.0 Foswiki-1.2.0
You can now delete the unpacked download
$ rm -rf /home/boy/Foswiki-1.2.0
Follow the standard installation instructions and get the test server running.

Abstract the configuration into Apache environment variables

In the Apache configuration, add the lines:
SetEnv FOSWIKI_HOST http://testserver
SetEnv FOSWIKI_INSTALL_PATH /home/boy/foswiki/Foswiki-1.2.0
SetEnv FOSWIKI_URL_PATH /wiki
  • FOSWIKI_HOST should be the same as {DefaultUrlHost} in LocalSite.cfg.
  • FOSWIKI_INSTALL_PATH should be the path to the root of the installation
  • FOSWIKI_URL_PATH should be the path (if any) relative to the FOSWIKI_HOST to the installation. We'll assume that you configured apache so that this is /wiki i.e. you accessed configure through the URL http://testserver/wiki/bin/configure.

Restart Apache.

Configure Foswiki from the environment variables

Now we have to make a couple of manual edits.

First, edit /home/boy/foswiki/Foswiki-1.2.0/bin/LocalLib.cfg and add the following lines:
# Untaint environment variables
$ENV{FOSWIKI_HOST} =~ /(.*)/;
$::FOSWIKI_HOST = $1;
$ENV{FOSWIKI_INSTALL_PATH} =~ /(.*)/;
$::FOSWIKI_INSTALL_PATH = $1;
$ENV{FOSWIKI_URL_PATH} =~ /(.*)/;
$::FOSWIKI_URL_PATH = $1;
$foswikiLibPath = "$::FOSWIKI_INSTALL_PATH/lib";
Save that and edit /home/boy/foswiki/Foswiki-1.2.0/lib/LocalSite.cfg.

Find and delete the line:
$Foswiki::cfg{DefaultUrlHost} = 'http://testserver';
and add the following lines at the start of the file:
$Foswiki::cfg{DefaultUrlHost} = $::FOSWIKI_HOST;
$Foswiki::cfg{InstallPath} = $::FOSWIKI_INSTALL_PATH;
$Foswiki::cfg{UrlPath} = $::FOSWIKI_URL_PATH;
In the rest of LocalSite.cfg, replace all occurrences of the following strings:
String Replace with
/home/boy/foswiki/Foswiki-1.2.0 $Foswiki::cfg{InstallPath}
/wiki $Foswiki::cfg{UrlPath}
Check that did this correctly by looking for the following settings:
$Foswiki::cfg{ScriptUrlPath} = '$Foswiki::cfg{UrlPath}/bin';
$Foswiki::cfg{ScriptDir} = '$Foswiki::cfg{InstallPath}/bin';
The http://testserver/wiki should still work.

ALERT! Foswiki versions earlier than 1.2.0 will issue a lot of warnings and errors in configure regarding the paths that you edited. You can ignore these warnings.

LocalLib.cfg and LocalSite.cfg no longer contain any server-specific information, so you can go ahead and check in to subversion. All files in the /home/boy/foswiki/Foswiki-1.2.0 tree should be committed.

Set up the "live" server"

To duplicate this installation on the production server http://wiki, log in to that server. Check out the Foswiki installation from subversion:
$ cd /opt/foswiki
$ svn co http://mysvnserver/trunk/Foswiki-1.2.0
Now, go through the Apache section of the Foswiki installation guide to configure the live server to use this installation. Do not run configure yet! When you edit httpd.conf add the lines:
SetEnv FOSWIKI_HOST http://wiki
SetEnv FOSWIKI_INSTALL_PATH /opt/foswiki/Foswiki-1.2.0
SetEnv FOSWIKI_URL_PATH /wiki
Restart the apache server, and your wiki should run.

Now, if you want to change the configuration, or install an extension, you do that on the test server. Use configure on the test server to install the extension, and make sure to svn add any files it installs. Once you are happy that the extension passes your own local tests, you can check in the changes. Now, to make the changes live, all you have to do is svn update the live server (caveat: if you are using an accelerator, such as mod_perl or fcgid you should also restart the Apache server).

The process above describes using a different copy of sources for each site. The advantage of this is that the live server and test server are totally isolated from each other. It's also possible using this technique to run multiple servers off the same copy of the sources, by applying the same SetEnv technique to the {PubDir} and {DataDir} configuration variables.

You'll note we haven't said anything about sharing webs between the two installs. That's because it's a bit out of scope for this description. FWIW, what I prefer to do is to rsync the production data and pub to the test server (or more usually a subset thereof). This data is not checked in to subversion. Using rsync means you can damage the data on the test server during testing without repercussions.

-- CrawfordCurrie - 05 Jul 2011
Topic revision: r1 - 05 Jul 2011, CrawfordCurrie
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy