Loading Configuration Based On Host and Environment

This tutorial is over a year old and may not apply to your version of Concrete CMS.
Dec 2, 2015

By default, concrete5 has a single database.php configuration file. This works well when you have a single machine or you can ensure that all the databases used in production and development share the same credentials. But what if they don't? What if you as a developer don't want to check your database credentials into your version control system?

The environment detection setup is for you. It's easy to use a custom database configuration file on your local setup, separately from the one used by the production server. Let's assume that production uses the regular database.php. It looks like this:

<?php
return array(
    'default-connection' => 'concrete',
    'connections' => array(
        'concrete' => array(
            'driver' => 'c5_pdo_mysql',
            'server' => 'db-server.wherever.com',
            'database' => 'mydatabase',
            'username' => 'username',
            'password' => 'password',
            'charset' => 'utf8'
        )
    )
);

First, copy this file, and add an identifier to the beginning of it. My name is Andrew, so I'm going to copy it and name it "andrew.database.php". Then I'm going to change my copied version to use my local database credentials

<?php
return array(
    'default-connection' => 'concrete',
    'connections' => array(
        'concrete' => array(
            'driver' => 'c5_pdo_mysql',
            'server' => 'localhost',
            'database' => 'awesome',
            'username' => 'andrew',
            'password' => 'superelite',
            'charset' => 'utf8'
        )
    )
);

Now, I simply have to tell concrete5 that, on my local machine, we need to use "andrew" configuration files, instead of the default ones. There are two ways to do this:

  1. Through the machine's hostname detection
  2. Through an environment variable

Using the machine's hostname for the environment detection

Let's get my hostname. The easiest way to do this in OS X is to use the terminal.

My host name is "Andrews-MacBook-Pro.local". So original.

Now, let's open up "application/bootstrap/start.php" in the application directory, and look down at the environment detection section. Normally it looks like this:

/**
 * ----------------------------------------------------------------------------
 * Detect the environment based on the hostname of the server
 * ----------------------------------------------------------------------------
 */
$app->detectEnvironment(
    array(
        'local' => array(
            'hostname'
        ),
        'production' => array(
            'live.site'
        )
    ));

return $app;

The hostname and live.site section are mock hostnames, and the array keys local and production that point to them are identifiers for configurations to use. Let's change it to understand that "andrew" exists, and map it to my host name.

/**
 * ----------------------------------------------------------------------------
 * Detect the environment based on the hostname of the server
 * ----------------------------------------------------------------------------
 */
$app->detectEnvironment(
    array(
        'andrew' => array(
            'Andrews-MacBook-Pro.local'
        )
    ));

return $app;

That's it! On the live site, "database.php" will be used (since it will always be falled back to if a mapped hostname override can't be found, but on my local machine any configuration files that start with "andrew" will be used if they're present.

Using an environment variable

In some occasions if you don not want to rely on the hostname of the computer, you can also use an environment variable named "CONCRETE5_ENV" to tell the system which environment configuration to use. With Apache webserver this is particularly easy if you have the mod_env module installed and enabled.

This module allows you to define the "CONCRETE5_ENV" environment variable through server config, virtual host block, directory block or your .htaccess file at the root of the concrete5 installation. Please note if you are using the .htaccess configuration file, this file should not be stored in your version control system.

When using the "CONCRETE5_ENV" environment variable, you also do not need to edit the environment detection block in "application/bootstrap/start.php" because when using this variable, you are already defining the environment for concrete5 to be running in, which makes the detection useless.

An example of defining this through the virtual host block:

<VirtualHost *:80>
    ServerName your.local.addr
    DocumentRoot "/www/concrete5_installation"

    # Define c5 environment
    SetEnv CONCRETE5_ENV andrew
</VirtualHost>

Remember to reload your webserver process after modifying its settings to apply them.

The same way you could simply add the same directive to the .htaccess file at the root of your concrete5 installation:

# At the top of the .htaccess file
SetEnv CONCRETE5_ENV andrew

Do not add the directive to both locations! Only use the one that best fits your needs or use some of the other configuration blocks where this setting can be defined.

As mentioned above, you need to have mod_env installed and enabled for Apache webserver to be able to use this. If you get HTTP 500 error page after adding this configurations directive or your webserver does not start properly after modifying the settings, you probably have not installed or enabled that module.

If you are using nginx webserver, you can use the "env" configuration directive to achieve the same result. More on this at the nginx documentation.

Other things to note

Once you get this working with the database config file, you can extend it to other config files. Any configuration file found in application/config can use this behavior. Want your own custom concrete.php config file, tailored to your local environment? You can create andrew.concrete.php the same way you created andrew.database.php.

Recent Tutorials
Upgrade Concrete versions 9.3.1 and 9.3.2
Sep 10, 2024
By myq.

How to get past a bug in versions 9.3.1 and 9.3.2 that prevents upgrading the Concrete core through the Dashboard

How to use Composer with Marketplace extensions
Aug 22, 2024

Composer can be used to manage third-party extensions from the marketplace

Controlling Google Tag Manager Tags Based on Concrete CMS Edit Toolbar Visibility
Aug 13, 2024

This document provides a step-by-step guide on how to control the firing of Google Tag Manager (GTM) tags based on the visibility of the Concrete CMS edit toolbar. It explains how to create a custom JavaScript variable in GTM to detect whether the edit toolbar is present on a page and how to set up a trigger that ensures GTM tags only fire when the toolbar is not visible. This setup is particularly useful for developers and marketers who want to ensure that tracking and analytics tags are not activated during content editing sessions, thereby preserving the accuracy of data collected.

Upgrading Concrete from 8.5 to 9.x
Jun 21, 2024
By myq.

How to avoid problems upgrading from 8.5 to 9.x

How to change the default date format
May 30, 2024
By myq.

Change the format of the default date

WebOps Tutorial on Running and Upgrading a Concrete CMS Website
May 2, 2024
By myq.

Describes how to deploy, manage, and upgrade a Concrete CMS website

Improvements?

Let us know by posting here.