Keep Environment Variables (and DB Info) Out of the Repo

Problem

You have multiple environments, and you want to keep environment-specific data out of your Git repo.

Solution

Use a file called _env.php to store all of your environment-specific data. Keep that file ignored from your repo.

Everything described here will be done in the /craft/config/ folder.

Step 1: Create a file called _env.php.example

When your site is added to a new environment, you’ll need to duplicate that file and call it _env.php. Make sure you add craft/config/_env.php to your .gitignore file.

Here’s an example of what your _env.php file should look like:

<?php

$customEnv = array(

    // Path info
    'baseUrl'  => '',
    'basePath' => '',

    // Database connection info
    'user'     => '',
    'password' => '',
    'database' => '',

    // General config settings
    'general' => array(
        // Config settings for this environment
    ),

);

Step 2: Modify your db.php file

<?php

// Get environment
require('_env.php');

return array(
    'server'      => '127.0.0.1',
    'user'        => $customEnv['user'],
    'password'    => $customEnv['password'],
    'database'    => $customEnv['database'],
    'tablePrefix' => 'craft',
);

Step 3: Modify your general.php file

<?php

// Get environment
require('_env.php');

return array(

    // Universal settings
    '*' => array(
        'omitScriptNameInUrls' => true,
        'enableCsrfProtection' => true,
        'environmentVariables' => array(
            'baseUrl'  => $customEnv['baseUrl'],
            'basePath' => $customEnv['basePath'],
        )
    ),

    // Custom environment settings
    parse_url($customEnv['baseUrl'], PHP_URL_HOST) => $customEnv['general']

);

That pulls the baseUrl and basePath from your environment config. The last line merges your environment’s general config settings with the universal config settings.

To recap, these files stay in the repo:

  • db.php
  • general.php
  • _env.php.example

…and this file gets ignored from the repo:

  • _env.php

That’s it! :)

Discussion

This solution was partially inspired by Matt Stauffer’s excellent blog post on Environment-Specific Configuration for CraftCMS Using PHPDotEnv. While Matt’s solution wasn’t a perfect fit for my needs, it definitely pointed me in the right direction!

Disclaimer: I am not a big Composer user, and was hesitant to include Composer and PHPDotEnv on a production server.