12th May 2015

Site configuration strategy (or how to manage your settings.php files)

Dan James
Senior Developer

Managing site configuration across multiple hosting and staging environments can get complicated, and if each one of these requires a settings.php file making sure that you consistently apply configuration can be a nightmare.

This is especially true when you start requiring different files at different points – it's very easy to lose track of which setting is where.

A typical example here at Deeson might be a site that's usually hosted on Acquia's platform, but that we need to be able to work locally on (we use our own variant of VDD for this).

That probably gives you 3 settings.php files: one for your local, one for the live domain name and one for Acquia's staging URLs. We'll also have different configuration for each of these. An example is where both reroute email and shield need to be disabled only on live, if our site has 3rd party integrations then we'll configure different API keys on staging and caching is always on on live.

So, how do we solve this?

In much the same way that we don't create a site-wide views feature, and instead we use a modular approach – for example one feature for news and another for events, we should do the same with our configuration and split it up. We don't do this by environment, but by module. So all the performance stuff together, all the security stuff together etc.

For example, you might have a reroute email file, that could read something like this:

$conf['reroute_email_address'] = "[email protected]";
$conf['reroute_email_enable_message'] = TRUE;
$conf['reroute_email_enable'] = TRUE;

if (SETTINGS_ENVIRONMENT === 'prod') {
  $conf['reroute_email_enable'] = FALSE;
}

This is clearer and less error prone than the situation that can occur where you can't instantly tell which setting will apply in a given situation. And by coding your conditions defensively you'll improve security.

So it's possible that you might still have those three settings.php files, but instead of adding config directly to them all they do is define the database settings and then do something like this:

<?php

/**
 * @file
 * Determine the environment and then load in the necessary settings.
 */

$base_domains = array(
  'mysite.dev' => 'local',
  'mysite.agency-dev-server.com' => 'dev',
  'dev-mysite.gotpantheon.com' => 'dev',
  'test-mysite.gotpantheon.com' => 'test',
  'www.mysite.com' => 'prod',
);

$platform = '';
$instance = $_SERVER['HTTP_HOST'];
$env = $base_domains[$_SERVER['HTTP_HOST']];

// Determine the environment, only use the ones that you will use.
if (isset($_SERVER['PANTHEON_ENVIRONMENT']) || isset($_ENV['PANTHEON_ENVIRONMENT'])) {
  $platform = 'pantheon';
}
elseif (isset($_SERVER['AH_SITE_ENVIRONMENT']) || isset($_ENV['AH_SITE_ENVIRONMENT'])) {
  require_once '/var/www/site-php/mysite/mysite-settings.inc';
  $platform = 'acquia';
}
elseif (file_exists('/var/www/vhosts/mysite.agency-dev-server.com')) {
  $platform = 'agency-server';
}
elseif (file_exists('/var/www/settings/mysite/settings.inc')) {
  require_once '/var/www/settings/mysite/settings.inc';
  $platform = 'vdd';
}

if (!empty($env) && !empty($platform) && !empty($instance)) {
  define('SETTINGS_ENVIRONMENT', $env);
  define('SETTINGS_INSTANCE', $instance);
  define('SETTINGS_PLATFORM', $platform);

  foreach (glob('sites/all/conf/*.settings.inc') as $file) {
    require_once $file;
  }
}

See that glob call? Create files in a new dir – sites/all/conf – like thing.settings.inc and place your config in there, using 'if' statements to react to the different envrionments.

Glob sorts by file name, so prefix each of these files with a number if you need them to be in a specific order, e.g 00-master.inc, 10-reroute-email.inc.

Here are some suggestions for files you might create (all to end in .settings.inc):

  • core (This should reflect the contents of settings.default.php)
  • master
  • warden
  • shield
  • reroute_email
  • mandrill
  • performance (caching, aggregation etc. Only force these on live, if you must)
  • your-api-here

In this manner we can create sets of default settings php files which are likely to be common across projects. This makes initial setup to our standards and best practice simple. Any deviation from the standards can then be configured and described in the main settings file for the site.