Developing a Facebook application causes people with “old school” configuration management heads (like mine) headaches. I suspect developing anything that relies heavily on callbacks to your address is equally painful.
Developing websites has a long history of “how to work”. Develop locally on a localhost stack like MAMP, WAMP, XAMPP or a pet linux box which you rest your feet on. Check your code into some form of version management and, when it comes time to deploy, shove it up via FTP or something similar. Lots of people have written about better ways to do it that this, and I’ll not try and duplicate it.
Working on a Facebook app we couldn’t exactly do this. The problem in the requirement for Facebook to be able to call back to your code, and thus your local development installation needs a publicly addressable URL, local.yoursite.com or something similar.
This is not difficult but once you take into account working from multiple locations, domestic broadband not being great for fixed IP’s etc, it’s not quite as simple as you hope. You can do neat things with SSH and local looping to redirect local.yoursite.com back to your machine too, which is not terribly hard, but it’s not a skill most people have without looking it up and fiddling a lot. There’s an online service called Tunnlr that helps remove some of the pain by doing it for you mind.
We went a different route however. We have server space to burn, and so we set up a subdomain each, and mount to locally using the very fabulous Expandrive over SSH. Now we can work locally on code, and it works wherever we are.
We have however modified the base install of CodeIgniter 1.7.2 to take into account “multi-siting”. The problem was that we kept checking out out code base using Mercurial, modifying the config files to take account of our subdomain, working on it, checking in, and pushing to live, thus pushing our dev/test subdomain’s config files into live and knackering it. We could have set hg ignore rules on the files to mean that out modifications were not checked in, but then if you come to modify the config files and need to push them into live for any reason, its a pain.
So, I set about adding some config to CI to mean that we could maintain a single set of config files, and that CodeIgniter would switch between them automatically depending on the subdomain it found itself running on. This does mean that the production usernames and passwords are hardcoded into our code that every developer sees, but as there only two of us, and we both have them anyway. “Deploy and replace style” config is more suitable when you need to keep secrets.
So what did I modify? Nothing huge: basically setup a site wide static value that determines which site we’re running on (test1.wishli.st, test2.wishli.st or live.wishli.st NB. these have all been changed to protect the innocent), and a set of case statements and IF’s to switch between config array.
First up, I added these lines to index.php (in the route directory):
// Multi-site Mod
// Add a case for each of the dev/test/live sites
switch ($_SERVER['HTTP_HOST']) {
case "live.wishli.st":
define('SITE_IDENTIFIER', 'live', TRUE);
break;
case "test1.wishli.st":
define('SITE_IDENTIFIER','test1', TRUE);
break;
case "test2.wishli.st":
define('SITE_IDENTIFIER','test2', TRUE);
break;
}
if (SITE_IDENTIFIER == 'live') {
// we are in live!
define('SITE_LIVE', TRUE);
} else {
// somewhere else - could be dev or individuals test
define('SITE_LIVE', FALSE);
}
This provides two statics, SITE_LIVE and SITE_IDENTIFIER. SITE_LIVE is a boolean that we can use to do things like only include Google Analytics trackers in live sites, or switch on debugging everywhere but live. SITE_IDENTIFIER is used to switch between different config sets.
Next up, modifications to all of the config files which are changed for each install.
system/applications/config.php:
// modify the base_url
// replaces the line $config['base_url'] = "http://www.example.com";
switch (SITE_IDENTIFIER) {
case "live":
$config['base_url'] = "http://live.wishli.st/";
break;
case "test1":
$config['base_url'] = "http://test1.wishli.st/";
break;
case "test2":
$config['base_url'] = "http://test2.wishli.st/";
break;
}
// Variable logging level - errors only in Live, debug in all others
// Replaces $config['log_threshold'] = 1;
$config['log_threshold'] = 2;
if (SITE_IDENTIFIER == "live") {
$config['log_threshold'] = 1;
}
system/application/database.php:
// define a different active group for each test suite
// currently we're using a shared test called dev
// this could be replaces with a case switch like config.php uses
// default active group is dev so we don't screw live
$active_group = "dev";
if (SITE_IDENTIFIER == "live") {
$active_group = "live";
}
// details removed, replace xxxx's and yyyy's
$db['dev']['hostname'] = "xxxx";
$db['dev']['username'] = "xxxx";
$db['dev']['password'] = "xxxx";
$db['dev']['database'] = "xxxx";
$db['live']['hostname'] = "yyyy";
$db['live']['username'] = "yyyy";
$db['live']['password'] = "yyyy";
$db['live']['database'] = "yyyy";
And making use of these switches in custom code:
$google_analytics_id = '';
if (SITE_LIVE) {
$google_analytics_id = 'xxxx';
} else {
$google_analytics_id = 'yyyy';
}
echo $google_analytics_id;
This might be a bit hacky, but it works well for us, and whilst it doesn’t scale up to a development team of 100 (or even three) it’s helped avoid the dreaded “pushing dev to live” horrors which so many people suffer.
Tags: codeigniter, config, configuration management, multi-site
