ExpressionEngine multiple environments with Master Config

ExpressionEngine has been our CMS of choice most of our projects at Anecka. ExpressionEngine is a great platform, but it does lack multiple environment configuration out of the box. Fortunately, thanks to Master Config by FocusLabs, configuring ExpressionEngine multiple environments is a snap.

ExpressionEngine multiple environments with Master Config

At Anecka we use multiple environments for all of our projects. We use our local environments for development, a staging environment for testing and finally our production or “live” environment. Unfortunately ExpressionEngine only has one set of configuration files, there’s no way to configure database or other settings separately.

Enter FocusLab’s Master Config, this excellent tool extends ExpressionEngine’s config file so you can define separate config files for each environment.

To make it easier to use master config, we adhere to the following structure:

/config
- config.env.php
- config.master.php
- config.local.php
- config.stage.php
- config.prod.php
/public_html
/system
/templates

You can see we keep ExpressionEngine’s system folder outside of the public folder. This is a recommended security practice. You’ll also notice instead of one config we have five. Two are provided by Master Config, config.env.php which will define our environments, and config.master.php does all the magic to make ExpressionEngine multiple environments work. Finally we define a specific config file for each environment, config.{env}.php. It doesn’t matter what “{env}” is, you just have to make sure it’s defined in config.env.php.

So how do we do that? Here’s an example of how we can configure config.env.php file:

if ( ! defined('ENV'))
{
switch (strtolower($_SERVER['HTTP_HOST'])) {
case 'mysite.com' :
define('ENV', 'prod');
define('ENV_FULL', 'Production');
define('ENV_DEBUG', FALSE);
break;

case 'stage.mysite.com' :
define('ENV', 'stage');
define('ENV_FULL', 'Staging');
define('ENV_DEBUG', FALSE);
break;

default :
define('ENV', 'local');
define('ENV_FULL', 'Local');
define('ENV_DEBUG', true);
break;
}
}

This bit of code checks the HTTP_HOST server variable and matches it against our environment urls. This is pretty powerful as ANY url you want can be checked. This can be extremely handy when paired with MSM (more on that later). If the host variable matches the case statement, we set the following PHP constants.

– ENV: this is the short code for the environment, it needs to match an existing config.{env}.php file (ex. ‘local’ = config.local.php)
– ENV_FULL: full name of the environment, it can be anything you want
– ENV_DEBUG: this can control the debug settings for each environment

Specifying the specific environment file is where the setting overrides occur. It’s a short file and contains three arrays you can modify: $env_db, $env_config, $env_global.

$env_db

This is the setting you’ll use the most, this will define the database configuration for the environment. For our development environments we DON’T check in config.local.php. This allows every developer working on our project to use their own database settings without overwriting each other’s (or the stage or production) configuration.

$env_db['hostname'] = 'localhost';
$env_db['username'] = 'user';
$env_db['password'] = 'password';
$env_db['database'] = 'mysite_db';

$env_config

This allows you to override ExpressionEngine’s configuration settings. For a complete list of overrides you can view them here (https://ellislab.com/expressionengine/user-guide/general/system_configuration_overrides.html). On most projects I like to set the site_url variable.

$env_config['site_url'] = 'http://mysite.dev/';

$env_global

Finally $env_global allows you to define global variables for each ExpressionEngine environment. These will get parsed into global ExpressionEngine tags. This is extremely powerful, for instance if you wanted to print out the IP address for each environment as a debug message you can store it in this array.

$env_global['ip_address'] = '127.0.0.1';

Using Master Config with Multiple Site Manager

The magic of Master Config really comes together when you pair it with Multiple Site Manager (MSM). Since you can define any host in config.env.php you can easily use it to configure your MSM sites. Here’s an example:

case 'mysite1.com' :
define('ENV', 'prod-mysite1');
define('ENV_FULL', 'Production');
define('ENV_DEBUG', false);
break;

case 'mysite2.com' :
define('ENV', 'prod-mysite2');
define('ENV_FULL', 'Production');
define('ENV_DEBUG', false);
break;

case 'mysite3.com' :
define('ENV', 'prod-mysite3');
define('ENV_FULL', 'Production');
define('ENV_DEBUG', false);
break;

Now you’ll just need to create a set of environment specific files: config.prod-mysite1.php, config.prod-mysite2.php, config.prod-mysite3.php.

/config/config.prod-mysite1.php

$env_db['hostname'] = 'localhost';
$env_db['username'] = 'username';
$env_db['password'] = 'password';
$env_db['database'] = 'mysite_db';

$env_config['site_name'] = 'mysite1'; //the MSM site_name short code
$env_config['cp_url'] = 'http://mysite1.com/admin.php';
$env_config['site_url'] = 'http://mysite1.com/';

Finally, in every public directory for each site managed by MSM make sure the following remains COMMENTED

/*
* --------------------------------------------------------------------
* Multiple Site Manager
* --------------------------------------------------------------------
*
* Uncomment the following variables if you are using the Multiple
* Site Manager: http://ellislab.com/expressionengine/user-guide/cp/sites
*
* Set the Short Name of the site this file will display, the URL of
* this site's admin.php file, and the main URL of the site (without
* index.php)
*
*/
/* Remain commented out as Master Config will configure these in the environment files */
/* $assign_to_config['site_name'] = '';
$assign_to_config['cp_url'] = '';
$assign_to_config['site_url'] = '';
*/

To help keep the relative file paths working together I recommend keeping all of the MSM public folders on the same level as each other and the ‘system’ folder.

/mysite1_html
/mysite2_html
/mysite3_html
/system

That’s it! Once you start using Master Config you’ll find all sorts of tricks you can use to run your ExpressionEngine multiple environments. If you found a great technique let me know in the comments.

Lessons learned: