Creating a Multi-Environment Config in ExpressionEngine 5

At Hippo, we’re constantly working on sites which involve multiple people. It’s standard practice these days to have an acceptable version control system and store source code in GIT, but how do you make sure that your site will operate across multiple environments without having to change configs each time?

The answer is just a little bit of work at the outset in your ./system/user/config/config.php file and you’ll be able to run your site on as many different environments as you want.

Set the basic variables

The first thing you need to do is to create some variables for your protocol, base path and base URL. Then you’ll need to set the name of your images folder and paths.

$system_folder = "system";

$protocol           = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ? "https://" : "http://";
$base_url           = $protocol . $_SERVER['HTTP_HOST'];
$base_path          = $_SERVER['DOCUMENT_ROOT'];

$images_folder      = "images";
$images_path        = $base_path . "/" . $images_folder;
$images_url         = $base_url . "/" . $images_folder;

Once you’ve done this, you’ll need to make some tweaks to the standard config variables to use these dynamic variables you’ve created.

$config['license_number']       = ‘X’;
$config['cp_url']               = $base_url.'/'.$system_folder.'/index.php';
$config['doc_url']              = '';
$config['is_system_on']         = 'y';
$config['allow_extensions']     = 'y';
$config['site_label']           = 'Site Label';
$config['site_name']            = 'Site Name';
$config['cookie_prefix']        = '';

$config['index_page']           = "";
$config['base_url']             = $base_url . "/";
$config['site_url']             = $config['base_url'];
$config['cp_url']               = $config['base_url'].$system_folder."/index.php";
$config['theme_folder_path']    = $base_path . "/themes/";
$config['theme_folder_url']     = $base_url . "/themes/";
$config['cp_theme']             = "default";
$config['emoticon_path']        = $images_url . "/smileys/";
$config['captcha_path']         = $images_path . "/captchas/";
$config['captcha_url']          = $images_url . "/captchas/";
$config['avatar_path']          = $images_path . "/avatars/";
$config['avatar_url']           = $images_url . "/avatars/";
$config['photo_path']           = $images_path . "/member_photos/";
$config['photo_url']            = $images_url . "/member_photos/";
$config['sig_img_path']         = $images_path . "/signature_attachments/";
$config['sig_img_url']          = $images_url . "/signature_attachments/";
$config['prv_msg_upload_path']  = $images_path . "/pm_attachments/";

We also, as a force of habit, add some additional config variables into our standard build including :

$config['profile_trigger'] = substr(md5(microtime()),rand(0,26),8);

This generates a random string for the ExpressionEngine profile trigger page every time the page is loaded to ensure you aren’t susceptible to member spam.

$config['disable_all_tracking'] = 'y';

These also turn off all tracking options, ensuring that your site is just that little bit faster and maximizes performance.

Finally we then have some of the default config options :

$config['show_profiler']        = 'n'; # y/n
$config['template_debugging']   = 'n'; # y/n
$config['save_tmpl_files']      = "y";  # y/n
$config['debug']                = "1"; # 0: no errors shown. 1: Errors shown to Super Admins. 2: Errors shown to everyone.
$config['enable_sql_caching']   = 'n'; # Cache Dynamic Channel Queries?
$config['email_debug']          = 'n'; # y/n

Handling Image Paths

ExpressionEngine has a handy config override for handling image paths and upload preferences, but you do need to create your entries first in the control panel. Once you’ve created them, you can use the $config['upload_preferences'] array to dynamically set their location and URL for multiple environments as follows:

$config['upload_preferences'] = array(
    1 => array(    // ID of upload destination (check control panel for the ID)
        'name'        => 'Images',  // Display name in control panel
        'server_path' => $base_path . '/assets/images/', // Server path to upload directory
        'url'         => $base_url . '/assets/images/'      // URL of upload directory
   2 => array(    // ID of upload destination (check control panel for the ID)
        'name'        => 'Videos',  // Display name in control panel
        'server_path' => $base_path . '/assets/videos/‘, // Server path to upload directory
        'url'         => $base_url . '/assets/videos/‘      // URL of upload directory

Creating Dynamic Database Connections

Finally, you’ll need to set up for multiple database connections. In our case, we use the URL host as a reference point. For example, I use client-name.localhost as local development environment, whereas someone else in my team will use I’ve also heard situations where developers use their name as the suffix, so client-name.carl and client-name.david etc, but, as long as the hostnames are unique, you can have as many environments as you wish. Here’s how we accomplish it.

switch($_SERVER['HTTP_HOST']) {

    case 'client-name.localhost':
        $dbConnection = array (
            'hostname' => 'localhost',
            'username' => 'user',
            'password' => 'password',
            'database' => 'dbname',

    case '':
        $dbConnection = array (
            'hostname' => 'localhost',
            'username' => 'user',
            'password' => 'password',
            'database' => 'dbname',

    case '':
        $dbConnection = array (
            'hostname' => '',
            'username' => 'staging-user',
            'password' => 'staging-password',
            'database' => 'staging-db',

    case '':
    case '':
        $dbConnection = array (
            'hostname' => '',
            'username' => 'live-user',
            'password' => ‘secretword’,
            'database' => ‘client_site_live’,

What we’ve done here is simply create a conditional variable called $dbConnection based on what the host address is. All we now need to do is apply this to the database config variable.

$config['database'] = array (
  'expressionengine' => $dbConnection

And there you go, you now have a config which will work for as many environments as you need. For every environment that you create, you simply create another case for it inside your switch block:

case 'client-site.david':
        $dbConnection = array (
            'hostname' => '',
            'username' => 'new-user',
            'password' => 'new-password',
            'database' => 'new-db',

If you’d like to see a complete version of the config file, please view it here.

Carl Crawley's avatar
Carl Crawley

Carl has been working with ExpressionEngine since 2006 and has been the Managing Director and Owner of Made by Hippo since 2010. Hippo specialise in ExpressionEngine, Craft CMS and Laravel based…

Comments 1

May 4, 2019


Hi Carl,

Thanks a lot to share this Multi-Environment Config. Very useful !