cool tech graphics

Stage-specific Drupal settings with local_settings.php

Filed under:

The decision to store settings.php in your version control system can be sticky. On one hand, there may be application-specific settings you would like to manage (perhaps the session lifetime, for example). On the other hand, it's a bad practice to store passwords in VCS, and some settings are host-specific. Perhaps you'd like to disable CSS aggregation on your development stage, or enable memcached only on your production stage.

Here is how I approach the problem:
I create a second config file, local_settings.php. Then I configure it to override anything in the main settings file by adding this to settings.php:

if (file_exists('./'. conf_path() .'/local_settings.php')) {
  include_once './'. conf_path() .'/local_settings.php';

settings.php is placed in version control, and local_settings.php is not. Upon deployment, the local settings file is then symlinked to a shared directory in each server.

Here are some ideas for your own local_settings.php file:

// Database settings
$db_url = 'mysqli://drupal:12345@localhost/drupal';
$db_prefix = '';
// Bypass almost all Drupal caches
$conf['cache_inc'] = 'includes/';
// Page cache
$conf['cache'] = CACHE_DISABLED;
// Block cache
$conf['block_cache'] = CACHE_DISABLED;
// Optimize CSS files
$conf['preprocess_css'] = CACHE_DISABLED;
// Optimize JavaScript files
$conf['preprocess_js'] = CACHE_DISABLED;
Date posted: September 15, 2009


Hello, this is an interesting trick.

I'll try it out at work today. Thanks!

Hi Dylan.

Thanks for this technique. We use subversion for development, and we ignore all environment-specific files (.htaccess, robots.txt, and settings.php) to prevent accidentally breaking production. Instead, we store the default versions of these files with .tmpl extensions so that developers can copy them and modify them to the needs of their development environments. Although we have scripts to automatically copy and set up these files, your technique eliminates this extra step for settings.php.

Thanks for sharing,

We use Subversion templates for this. The template is named template.php.tmpl, and SVN automatically handles this. Our base configurations go into the template, and on different environments, we simply copy the template to settings.php and make any environment-specific settings.

The benefit to this is that the template contains all of the shared configurations while still allowing for localized configurations.

We use the same settings file for dev and production and just use a standard convention for dev site hostname [siteid]

Then the settings file has a condition for whether its dev or production so we never have to change the file, just move it from dev to prod. We also keep any variables that change with hostnames such as securepages_basepath_ssl, securepages_basepath, etc in the settings file so the db moves easily from dev to prod.

The template approach never quite worked for us because the variables are derived by convention. On a typical site, we just need a site_id and production hostname and the rest of the variables can be derived from it.

Here's a drupal 6 settings file. The "slippers" prefix is just a way of avoiding other namespaces.

// need switch here to easily move from dev to prod and back without glitches.
// so convention of [siteid]-dev... needs to be maintained in dev sites.
global $slippers_dev, $slippers_db_param, $slippers_site_id, $slippers_recover;
$slippers_site_id = "zzz";
$slippers_dev =  (strpos($_SERVER['HTTP_HOST'],"-dev.") > 0) ? TRUE : FALSE;
$slippers_db_param['host'] =  'localhost';
if ($slippers_dev) {
    error_reporting(E_ALL  & ~E_NOTICE);
    $slippers_db_param['databasename'] = $slippers_db_param['username'] = $slippers_site_id ."_dev_drpl";
    $base_domain = $slippers_site_id  .'';
    $base_url = 'http://'. $base_domain;
    $cookie_domain = $slippers_site_id .'';
    $conf['securepages_basepath_ssl'] = "https://". $base_domain;
    $conf['securepages_basepath']  = "http://". $base_domain;
else {
    error_reporting(E_ALL  & ~E_NOTICE);
    $slippers_db_param['databasename'] = $slippers_db_param['username'] = $slippers_site_id ."_prd_drpl";
    $base_domain = '';
    $base_url = 'https://' . $base_domain;
    $cookie_domain = '';
// $conf array are drupal variables that cannot be overridden by db settings.
$conf['file_directory_temp'] = "sites/default/files/tmp";
$conf['file_directory_path'] = "sites/default/files";
$db_url = "mysqli://". $slippers_db_param['username'] . ":" .  $slippers_db_param['password'] ."@" . $slippers_db_param['host'] . "/".  $slippers_db_param['databasename'];
$db_prefix = '';
// recovery, debug, and migration helper settings.
$slippers_recover = FALSE;
if ($slippers_recover) {
  $conf['cache'] = FALSE;
  $conf['theme_default'] = 'garland';
  $conf['clean_url'] = TRUE; 
  $conf['preprocess_css'] = FALSE;
  $conf['preprocess_js'] = FALSE;
ini_set('upload_max_filesize', '10000000');
ini_set('arg_separator.output',     '&amp;');
ini_set('magic_quotes_runtime',     0);
ini_set('magic_quotes_sybase',      0);
ini_set('session.cache_expire',     200000);
ini_set('session.cache_limiter',    'none');
ini_set('session.cookie_lifetime',  2000000);
ini_set('session.gc_maxlifetime',   200000);
ini_set('session.save_handler',     'user');
ini_set('session.use_only_cookies', 1);
ini_set('session.use_trans_sid',    0);
ini_set('url_rewriter.tags',        '');
$update_free_access = FALSE;

Hot. This is my new solution now.

Have you changed this technique at all for Drupal 7?

$db_url has been replaced by an array in D7, but the technique is the same.

Add new comment

Restricted HTML

  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.


Have questions?