CodeIgniter Forums
Using CI in "blue-green" deployment - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forum-5.html)
+--- Forum: Best Practices (https://forum.codeigniter.com/forum-12.html)
+--- Thread: Using CI in "blue-green" deployment (/thread-71632.html)



Using CI in "blue-green" deployment - mfox - 09-07-2018

Hey guys, happy Friday!

I've been reading a lot about the "blue-green" deployment plan lately, and I was wondering how that works with CI.  To save you a Google search or two, this plan for deploying web apps basically has two production servers, but only one is actively used by end-users; the other one is a testing environment for the next version.  When a new version is ready, the router switches the two (so that all requests are sent to the new version, and the old is there as an emergency backup).  This makes a lot of sense at a high level, but it kind of raises a lot of questions in practice.  Specifically:

1. How does this work when database structure changes?

Wouldn't the DB have to be changed on both the "blue" and the "green" servers?  That wouldn't be as easy to undo if something goes wrong.  I have a feeling this is where CI's database "migrations" API comes in (?).  I haven't used it, but once I discovered it I read the docs on it.  I think it might help here (or would it?)

2. How does this work with CI's config files?

For example, settings like base_url and database connection variables will probably be different between the two servers.  Maybe I'm not understanding the whole blue-green thing correctly, but if one is a testing environment then logically it should have test/dummy data.  Either way, I think this means some manual file-swapping or other change would be involved.  Or do you just do something like:

$config['whatever'] = ENVIRONMENT == 'production' ? 'set this way' : 'set that way';   // ?

Anyway, thanks for your help and have an amazing weekend! Smile


RE: Using CI in "blue-green" deployment - albertleao - 09-07-2018

Hello!

I'm assuming you're going to be automating your blue-green deployment. I've done this on AWS using both Opsworks and ElasticBeanstalk and had it working.

For database changes, you have to use migrations. Manually updating the database is a terrible idea when trying to automate deployments. If you're not a fan of CI's migrations, there are several other tools that you can use too. I quite enjoy Phinx.

When it comes to config files, it's a good idea to put them in an environment variable so you'll access with $_SERVER. Every automation tool i've dealt with has given an option to inject those env variables on deploy or launch


RE: Using CI in "blue-green" deployment - skunkbad - 09-07-2018

This sort of reminds me of WP Engine. They have a 1-click staging environment setup. You can work on staging, then deploy back to production. At least that's the theory. What generally happens is that we do the real work on development servers, and the staging environment serves as a testing environment. Since we work remotely, having the staging environment is nice, because then we can fiddle around and talk about things, and test things. It's not as glamorous as it seems.


RE: Using CI in "blue-green" deployment - mfox - 09-10-2018

Good morning,

Thanks for the quick responses. I re-read the CI migration docs and also read up on Phinx. Phinx looks like it already does a lot of the same stuff as CI. And not just migrations either - it's a complete API for all things database, that looks (IMO) very similar to CI's. So let me ask you this: Is there any reason to prefer Phinx over what CI comes with "out of the box"? At this point the only real advantage I could see is that Phinx tries to automatically figure out the path to roll back changes if necessary.

But I'm not sure I get what you mean about the config files. I know I can do stuff like:

$_SERVER['foo'] = 'bar';

But I'm not sure I understand exactly what you mean by saving config data there. I know putting the config data into the global variable would make it available to my models/controllers, but how does that solve the test vs. production problem?


RE: Using CI in "blue-green" deployment - php_rocs - 09-10-2018

@mfox,

Here is a link to the description of the CI config file: https://codeigniter.com/user_guide/libraries/config.html?highlight=config#config-class


Here is a link to the CI overview https://codeigniter.com/user_guide/overview/index.html#codeigniter-overview


RE: Using CI in "blue-green" deployment - mfox - 09-10-2018

You know, you could have just said "rtfm", lol. Smile

But all joking aside, thank you for the link on the config CLASS. That part I didn't know, and that did lead to something (though it's something that just raises more questions about albertleao's post). It said, "To create an environment-specific configuration file, create or copy a configuration file in application/config/{ENVIRONMENT}/{FILENAME}.php". This page tells me a few things:

1. I wouldn't need to save my settings to something like $_SERVER, because I can just use this config class if I really need to access config data from my code (which I really don't see a need for). (like $this->config->item('whatever') instead of $_SERVER['whatever]).

2. I can have the things that change from development to production in folders for the different environments, and CI will load the ones that correspond to the current setting.

3. So I could just change the global ENVIRONMENT variable (not "an environment variable" in the OS sense) when deploying to production, and CI would load the right config files. I already do that anyway, so this could definitely work!

Is that what you were shooting for, albertleao?

PS: Thanks to all who posted here - I think I got what I was looking for. Smile


RE: Using CI in "blue-green" deployment - Pertti - 09-10-2018

When setting up config files, you can reference environmental variables:

PHP Code:
$db['default'] = array(
    
'dsn'    => '',
    
'dbprefix' => '',
    
'hostname' => getenv('DB_HOST'),
    
'database' => getenv('DB_DATABASE'),
    
'username' => getenv('DB_USERNAME'),
    
'password' => getenv('DB_PASSWORD'),
    
'dbdriver' => getenv('DB_CONNECTION'),
... 

That way the code does not change, but your dev, staging, testing and production and production temp could all use what ever you set for said instance is required.

For database, as mentioned before, doing it manually could get very painful, especially when you have multiple people with multiple dev instances running.

I ended up writing my own little patch system, but I assume most of the systems work in same way - they somehow bookmark most recent applied batch, which will be unique per instance, and it then can figure out what batches and in what order it needs to run to be up to date.

The main problem with DB is that it could take some time to change sometimes, if you have huge amount of data, but you could try to have backwards compatible approach, if possible. Basic example - you add new field to DB, by giving it default value the old app can still add these records in DB, with built in default value feature, and new app knows to use app data if available.