20 Jan

hosting multiple sites from the same CMS engine

I posted about webwork.ie‘s free website engine a few days ago. In the comments, Mickster asked how he would go about doing it himself.

I haven’t studied how other engines do it, but here’s how I do it.

First off, some benefits to sharing the CMS across separate sites:

  • Reduced resource usage. Because a single PHP engine is used, it is easier to optimise using RAM-disks, PHP caching, and other optimisations.
  • Easier upgrades – upgrade one system, upgrade them all!
  • Easier bug-fixing. One of the banes of my life is discovering a bug in a CMS that you know exists in at least ten other instances of that CMS. Now, you fix the bug in one place, and it’s fixed everywhere!

Convinced yet? Of course you are. Here’s how you do it.

First, separate all site-specific files from your engine files. To do this, you need to strictly keep your uploaded files and site-specific CSS in separate from your executable PHP. After doing this step, you should be able to clearly point out directories in your CMS and say “those are the engine’s executables and other resources, these are the design files and other uploadables which are site-specific.”

Second, all site-specific resources should be served through a script. The reason for this is that we are going to be moving the files away from the perceived directory that they’re in. Instead of, say, a web root of /home/webme/public_html/ with an image located at /home/webme/public_html/i/image.jpg, you might have the image located at /home/webme/sites/webme.eu/i/image.jpg, and another image from a different site located at /home/webme/sites/an-other-site.com/i/image.jpg. The choice of which image to show when /i/image.jpg is referenced depends then on the domain-name the browser requested the file from.

Then you need to over-ride the config at the time of its request. In the WebME CMS, the config file is located at /.private/config.php. What we want is to replace that with a “proxy” config file which, when included, checks the domain name and includes the real config file.

So how does the proxy config know where the real one is located? the way I handle this is to have a directory named after the site, located in /home/webme/sites/$NAME. If, for example, blah.webme.eu or www.blah.webme.eu is requested, you strip off any leading www. strings and trailing webme.eu strings with a regexp, and check to see if the config (/home/webme/sites/blah/config.php) exists. If so, include it.

To handle aliases, for example, if you wanted www.blah.com to load the blah.webme.eu site, you create a directory /home/webme/sites.aliases/$NAME, where $NAME (blah.com) is a symbolic link pointing to the correct directory.

It’s not a difficult trick, but it works.

Here’s my proxy config file:

Here is a copy of the proxy file that I use in webme.eu’s multi-user engine.

<?php
$host=preg_replace('/^www\.|\.webme.eu$/','',strtolower($_SERVER['HTTP_HOST']));
$cfile='/home/webme/sites/'.$host.'/config.php';
if(!file_exists($cfile)){
        $cfile='/home/webme/sites.aliases/'.$host.'/config.php';
        if(!file_exists($cfile)){
                header('Location: http://webme.eu/');
                exit;
        }
}
require $cfile;
define('CONFIG_FILE',$cfile);

4 thoughts on “hosting multiple sites from the same CMS engine

  1. Pingback: klog » Blog Archive » hosting multiple sites from the same CMS engine

  2. Pingback: Kae Verens’ Blog: Hosting multiple sites from the same CMS engine | How2Pc

  3. Wow, my “own” blog post – thanks Kae!

    This helps a lot – I spent at least 4 hours trying different setups in my .htaccess but, as I mentioned, all it led to was a rewrite loop…

    Haven’t tried the proxy yet, but will do.
    In combination with serving the file through a script (as you describe here: http://verens.com/archives/2009/01/13/serving-files-through-a-script/) and a little touch of this http://verens.com/archives/2008/07/27/pre-parsing-html-for-incorrectly-sized-images/ to set up some automatic resizing and caching of images.

    Only question so far:
    How is performance affected when serving files through a script? Instead of getting the file directly, it first goes to a script, which in turn outputs the file – are there any performance downturns worth to mention?

    Thanks alot Kae, you’re a big help!

    Best Regards,
    Mickster

Comments are closed.