Guidelines for setting up Development, Testing and Production Environments

edited June 2011 in Share
Hello,

I would like to start a discussion on strategies/guidelines both the Fuel developers and the end users have in regards to setting up your configuration to take into account testing versus production environments. I was evaluating PyroCMS, another CI CMS and they have some default syntax in the root index.php file that accomodates different testing environments. I tweaked a few things to match my environment, which includes the following 4 environments:

1) Localhost (my development machine)
2) Development (the remote development server, which connects to a dev_ database)
3) Staging (the remote staging server, which connects to the live database)
4) Production (the live production server, which also connects to the live database)

I modified PyroCMS's index.php file to look like the following:

/*
*---------------------------------------------------------------
* APPLICATION ENVIRONMENT
*---------------------------------------------------------------
*
* You can load different configurations depending on your
* current environment. Setting the environment also influences
* things like logging and error reporting.
*
* This can be set to anything, but default usage is:
*
* development
* testing
* production
*
* NOTE: If you change these, also change the error_reporting() code below
*
*/

// Local: localhost or local.example.com
if ($_SERVER['SERVER_NAME'])
{
// Local Development: localhost
if (strpos($_SERVER['SERVER_NAME'], 'local.') !== FALSE OR $_SERVER['SERVER_NAME'] == 'localhost' OR strpos($_SERVER['SERVER_NAME'], '.local') !== FALSE)
{
define('ENVIRONMENT', 'local');
}

// Development: dev.thehubway.com
elseif (strpos($_SERVER['SERVER_NAME'], 'dev.') === 0)
{
define('ENVIRONMENT', 'dev');
}

// Staging: test.thehubway.com
elseif (strpos($_SERVER['SERVER_NAME'], 'test.') === 0)
{
define('ENVIRONMENT', 'test');
}

// Production: thehubway.com
else
{
define('ENVIRONMENT', 'production');
}
}
else
{
define('ENVIRONMENT', 'local');
}

/*
*---------------------------------------------------------------
* ERROR REPORTING
*---------------------------------------------------------------
*
* Different environments will require different levels of error reporting.
* By default development will show errors but testing and live will hide them.
*/

switch (ENVIRONMENT)
{
case 'local':
error_reporting(E_ALL);
case 'dev':
error_reporting(E_ALL);
break;

case 'test':
error_reporting(0);
case 'production':
error_reporting(0);
break;

default:
exit('The application environment is not set correctly.');
}

Just would like to get your feedback on whether this is the correct approach for Fuel or not. Fuel's default code in its index.php file is simply this:

/*
*---------------------------------------------------------------
* APPLICATION ENVIRONMENT
*---------------------------------------------------------------
*
* You can load different configurations depending on your
* current environment. Setting the environment also influences
* things like logging and error reporting.
*
* This can be set to anything, but default usage is:
*
* development
* testing
* production
*
* NOTE: If you change these, also change the error_reporting() code below
*
*/
define('ENVIRONMENT', 'development');
/*
*---------------------------------------------------------------
* ERROR REPORTING
*---------------------------------------------------------------
*
* Different environments will require different levels of error reporting.
* By default development will show errors but testing and live will hide them.
*/

switch (ENVIRONMENT)
{
case 'development':
ini_set('display_errors', 1);
error_reporting(E_ALL);
break;

case 'testing':
case 'production':
error_reporting(0);
break;

default:
exit('The application environment is not set correctly.');
}


Thanks,
Erik

Comments

  • edited 3:16AM
    So here's an update: I integrated the code I showed above that originally came from PyroCMS (which is just a big if statement checking for a particular URL and setting an environment variable value based on whether it contains the word localhost, dev, test, or just simply has the server name included in the path.)

    At this point, it doesn't appear to be picking up the settings properly because when I go to my test site (dev.thehubway.com) it says it can't find one of the fuel tables. This is because I have 2 databases (one called "servername" and one called "servername_dev") and Fuel is trying to connect to the database called "servername", which I haven't put any tables into yet. I'm trying to get the dev server to use the database called "servername_dev" instead of "servername".

    I also noticed that if I remove this code:

    $db['default']['hostname'] = 'localhost';
    $db['default']['username'] = 'username';
    $db['default']['password'] = 'password';
    $db['default']['database'] = 'servername';
    $db['default']['dbdriver'] = 'mysql';
    $db['default']['dbprefix'] = '';
    $db['default']['pconnect'] = TRUE;
    $db['default']['db_debug'] = TRUE;
    $db['default']['cache_on'] = FALSE;
    $db['default']['cachedir'] = '';
    $db['default']['char_set'] = 'utf8';
    $db['default']['dbcollat'] = 'utf8_general_ci';
    $db['default']['swap_pre'] = '';
    $db['default']['autoinit'] = TRUE;
    $db['default']['stricton'] = FALSE;

    it breaks the site, even though my environment configuration handles the different production environment cases:

    // Local
    $db['local']['hostname'] = 'localhost';
    $db['local']['username'] = 'username';
    $db['local']['password'] = 'password';
    $db['local']['database'] = 'servername';
    $db['local']['dbdriver'] = 'mysql';
    $db['local']['dbprefix'] = '';
    $db['local']['stricton'] = TRUE;
    $db['local']['active_r'] = TRUE;
    $db['local']['pconnect'] = TRUE;
    $db['local']['db_debug'] = TRUE;
    $db['local']['cache_on'] = FALSE;
    $db['local']['cachedir'] = '';
    $db['local']['char_set'] = 'utf8';
    $db['local']['dbcollat'] = 'utf8_unicode_ci';
    $db['local']['port'] = 3306;

    // Dev
    $db['dev']['hostname'] = 'localhost';
    $db['dev']['username'] = 'username';
    $db['dev']['password'] = 'password';
    $db['dev']['database'] = 'servername_dev';
    $db['dev']['dbdriver'] = 'mysql';
    $db['dev']['dbprefix'] = '';
    $db['dev']['stricton'] = TRUE;
    $db['dev']['active_r'] = TRUE;
    $db['dev']['pconnect'] = TRUE;
    $db['dev']['db_debug'] = TRUE;
    $db['dev']['cache_on'] = FALSE;
    $db['dev']['cachedir'] = '';
    $db['dev']['char_set'] = 'utf8';
    $db['dev']['dbcollat'] = 'utf8_unicode_ci';
    $db['dev']['port'] = 3306;

    // Staging
    $db['test']['hostname'] = 'localhost';
    $db['test']['testname'] = 'username';
    $db['test']['password'] = 'password';
    $db['test']['database'] = 'servername';
    $db['test']['dbdriver'] = 'mysql';
    $db['test']['bprefix'] = '';
    $db['test']['stricton'] = TRUE;
    $db['test']['active_r'] = TRUE;
    $db['test']['pconnect'] = TRUE;
    $db['test']['db_debug'] = TRUE;
    $db['test']['cache_on'] = FALSE;
    $db['test']['cachedir'] = '';
    $db['test']['char_set'] = 'utf8';
    $db['test']['dbcollat'] = 'utf8_unicode_ci';
    $db['test']['port'] = 3306;

    // Production
    $db['production']['hostname'] = 'localhost';
    $db['production']['username'] = 'username';
    $db['production']['password'] = 'password';
    $db['production']['database'] = 'servername';
    $db['production']['dbdriver'] = 'mysql';
    $db['production']['dbprefix'] = '';
    $db['production']['stricton'] = TRUE;
    $db['production']['active_r'] = TRUE;
    $db['production']['pconnect'] = TRUE;
    $db['production']['db_debug'] = TRUE;
    $db['production']['cache_on'] = FALSE;
    $db['production']['cachedir'] = '';
    $db['production']['char_set'] = 'utf8';
    $db['production']['dbcollat'] = 'utf8_unicode_ci';
    $db['production']['port'] = 3306;

    The expected behavior here would be that Fuel would use configuration lines starting with $db['dev'] on my dev server instead of $db['default'] based on the code in my index.php file that checks for the dev subdomain in the URL.

    Thanks for your help, would appreciate some guidance as to how I can properly set up this so that my dev server connects to its own database that is separate from the staging and production server database.

    Erik
  • edited 3:16AM
    If you look at the fuel/codeigniter/database/DB.php, line 31 of the file, CodeIgniter is looking for separate configuration files in subfolders with the same name as your dev environment. If it doesn't find it, then it defaults to the main config file. So if you create a subfolder in your fuel/application/config named "dev" and put a database.php configuration file in there pointing to your dev database, it should use that.

    Also, you can add other configuration files to that folder and CI will look in your ENVIRONMENT folder first before defaulting to the main config folder (see the fuel/codigniter/core/Config.php file line 88). Hope that helps.
  • edited 3:16AM
    I fixed it, yay! Here is the ticker:

    $active_group = ENVIRONMENT;

    It is set to 'default' normally, so using the ENVIRONMENT constant allows that to switch dynamically.

    Your idea would work too, and maybe that's something I would consider doing. Do you think I should go the route of creating a separate config folder named "dev" or is modifying the database.php file ok from a system integrity standpoint/upgradability standpoint? I would think when upgrading to basically backup database.php before doing any merges, so it's probably ok.

    Erik
  • edited 3:16AM
    Although I can't guarantee anything, that's a pretty safe file to change. It requires you to change it anyway to your own DB settings. Glad you figured it out. I think your way works just as good and may be easier to maintain for you.
Sign In or Register to comment.