Loading Configuration Based On Host and Environment

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
Update jQuery to 3.5 on Concrete CMS version 8.5.x
Dec 1, 2021
By hissy.

If you have to take some time to fix your site to work with version 9 and want to update jQuery immediately, you can override it.

Add-On Developers: Get Your Add-Ons Ready for Concrete CMS 9.0
Aug 6, 2021
By andrew.

Concrete CMS 9.0 is coming! But there are some changes in version 9 that might affected your add-ons and themes. This document aims to answer questions about the most common ways that your add-ons might need to be changed, and common problems you'll run into.

Permissions for editors in a multilingual site
Jun 2, 2021
By myq.

How to set up a multilingual Concrete CMS site for groups of language-specific editors

Getting Started with Doctrine in Concrete CMS
Jan 20, 2021
By linuxoid.

Doctrine is a very flexible, simple (once you get to know it better) and powerful PHP library for database interactions primarily focused on the ORM = Object Relational Mapping and DBAL = DataBase Abstraction Layer.

How To Upgrade PHP Using the MultiPHP Manager In cPanel
Nov 23, 2020

This article will explain how to upgrade your PHP version using cPanel.

How To Add Google Analytics To Your Website - The easy way
Oct 9, 2020

Adding analytics to your website is an important part of running your website. There’s no need to edit your theme or install a plugin to add a tracking code to Concrete CMS you can do it right from the CMS.

Was this information useful?
Thank you for your feedback.