Archive Old post. Originally published 19 February 2014 on the WordPress version of this site. Preserved here for the search engines and the curious. Old me had opinions.
Developer 3 min read

Proper Big Boy Follow Up

This is a bit of a follow up to a question I posted last week. I was struggling with deployment options for my app and more specifically how I could differentiate between configurations. I’d thought I would share how I did it.

Environment Variables

Some people like to use these for everything, I didn’t want to go that far but it seemed like a good starting point so I created one.

SetEnv CAKE_ENV development

Adding this to my httpd.conf allowed me to set easily and in a single place on all my web servers what environment to use. So I could set it to development, staging or production depending on the server I was on. Make sure to restart Apache after adding this!

Hey Cake look at my Environment

So it might be a little hacky but the first thing I did was create three files: App/Config/development.php, App/Config/staging.php, App/Config/production.php of course you can put these in a sub-folder if you really want to! Next up I wanted to include the correct file depending on what I had specified as my environment. In my App/Config/core.php I placed the following:

// Get Environment from Apache
$environment = getenv( 'CAKE_ENV' );

// Load our environment settings based on our environment
if ( $environment == 'development' ) {
	include APP . 'Config' . DS . 'development.php';
} elseif ( $environment == 'staging' ) {
	include APP . 'Config' . DS . 'staging.php';
} elseif ( $environment == 'production' ) {
	include APP . 'Config' . DS . 'production.php';
} else {
	include APP . 'Config' . DS . 'development.php';
}

// Get our config and place it in variable
$myConfig = Configure::read( 'myEnvironment' );

So here we get the file based on our environment variable and if none is set we stick to default. Finally I setup a variable for my config stuff. More on that in a minute!

Environment Files

So I needed to store some useful info:

<?php // App/Config/development.php 
Configure::write( 'myEnvironment', array( 		
                'debug' => 2,

		'session_defaults' => 'php',
		'session_cookie' => 'WOWZERS',

		'cache_disable' => true,
		'cache_prefix' => 'solutions_',
		'cache_engine' => 'Apc',
		'cache_duration' => '+10 seconds',

		'DB_HOST' => 'my_data_base_host',
		'DB_NAME' => 'my_dev_db'
	)
);

So you can see we have a simple config write and then a few things I change in my app depending on the environment they should all be self-explanatory. Obviously I can change them like so:

<?php // App/Config/production.php 
Configure::write( 'myEnvironment', array( 		
                'debug' => 0,

		'session_defaults' => 'php',
		'session_cookie' => 'WOWZERS',

		'cache_disable' => false,
		'cache_prefix' => 'solutions_',
		'cache_engine' => 'Apc',
		'cache_duration' => '+30 days',

		'DB_HOST' => 'my_database_host',
		'DB_NAME' => 'my_live_db'
	)
);

Calling our Variables

Now we have a Config variable we can use anywhere in our app. Let’s take a look at an example in my core.php file:

$mySetup = Configure::Read( 'myEnvironment' );

Configure::write( 'debug', $mySetup['debug'];
Configure::write( 'Session', array(
		'defaults' => $mySetup['session_defaults'],
		'cookie' => $mySetup['session_cookie']
	) );

These are only a couple of examples. You can also do the same in your bootstrap.php as and when you need to:

$mySetup = Configure::read( 'myEnvironment' );

Cache::config( 'short', array(
		'engine' => $mySetup ['cache_engine'],
		'duration' => '+1 hours',
		'path' => CACHE . DS . 'short' . DS,
		'prefix' => $mySetup ['cache_prefix'] . 'cake_short_'
	)
);

Database

This is the really useful bit, this is how you can manage your database settings for different environments.

Note: I am using MSSQL on Windows (Don’t judge me) so my authentication is done outside of these config files. You probably shouldn’t include your database connection settings (username/password) in your repo. These would be better set as environment variables like we did right at the start.

We can use a similar method as in previous examples to get our database connection parameters. This does need to be in the __construct() method like so:

<?php class DATABASE_CONFIG {     
    public $default;     
    public function __construct() {         
        $this->default = array(
            'datasource' => 'Database/Sqlserver',
            'persistent' => 'false',
            'host' => Configure::read( 'myEnvironment.DB_HOST' ),
            'database' => Configure::read( 'myEnvironment.DB_NAME' )
        );
    }
}

Easy? Seems to do the job doesn’t it? It works for me anyway…


Filed under Developer. No comments, on purpose.