CloudFoundry Rails Deployment
cf-deploy makes it easy to:
- Deploy your rails app with one rake command
- Implement blue/green deployments
- Run asset precompiles before deploying your app
- Automate your rails deploys using jenkins, circle-ci, codeship
The functionality comes in the shape of generated rake tasks. You require this
gem in your
Rakefile and call the
.rake_tasks! setup method.
require 'cf-deploy' CF::Deploy.rake_tasks!
By default tasks will be created for each manifest in your
If you have a
production.yml you can now run the following
bundle exec rake cf:deploy:staging bundle exec rake cf:deploy:production
You now have rake tasks that run
cf push -f manifests/staging.yml and
cf push -f manifests/production.yml. Things start to get more exciting
when you define your environments in your
Rakefile along with their task
dependencies just like normal rake task syntax.
require 'cf-deploy' CF::Deploy.rake_tasks! do environment staging: 'assets:precompile' environment production: [:clean, 'assets:precompile'] end
Now when running
cf:deploy:production the prerequisite
tasks will be run first.
The next thing to talk about is route mapping. You can define a route in a an environment block like so:
require 'cf-deploy' CF::Deploy.rake_tasks! do environment staging: 'assets:precompile' do route 'example.com', 'staging' end environment production: [:clean, 'assets:precompile'] do route 'example.com' route 'example.com', 'www' route 'example.com', 'www-origin' route 'example.com', 'admin' end end
As soon as an environment with routes is pushed successfully each of it's routes will be mapped to all the applications defined in the environment's manifest.
And then things get super interesting when you start talking blue/green.
What is blue/green deployment?
Simply put, blue/green deployment allows you to deploy a new version of your app, test it on a private URL and then direct your traffic to the new version when you are ready.
You have two applications for one environment, say production. One version is called green, the other is blue. The first time you deploy your environment either green or blue can be deployed. Thereafter, any changes you want to deploy you deploy to the color that doesn't have your production domain pointed at it. You test it on a private URL and then when you're happy you flip your domain to point at that. If something then goes wrong you can then flip your domain back to the last working version.
This gem provides rake tasks for you to deploy using this methodology as well as the standard single app deployment process on a CloudFoundry provider.
An example of blue/green
Examples always help and this example is probably the most common use case. You might have a straight forward deployment for staging but use the blue/green strategy for production. Here is what your Rakefile might look like:
require 'cf-deploy' CF::Deploy.rake_tasks! do environment staging: 'assets:precompile' environment production: 'assets:precompile' do route 'example-app.io', flip: true route 'example-app.io', 'www', flip: true route 'example-app.io', 'www-origin', flip: true route 'example-app.io', 'blue', blue: true route 'example-app.io', 'green', green: true end end
You should also have three manifests defined:
When you run
cf:deploy:production for the first time (assuming neither
production_green.yml are deployed) your blue app will
be deployed and route setup.
cf:deploy:production thereafter will deploy which ever version isn't
currently deployed. Your route(s) will not be mapped automatically this time.
Nows your chance to checkout your new deployment using an alternate route. When
you're happy and want to map your route across run:
bundle exec rake cf:deploy:production:flip
You need the
cf command installed already. Grab the latest release from
the CloudFoundry CLI repo on github.
You then need to install this gem in your project's
gem 'cf-deploy', '0.1.4'
Defining CloudFoundry details in your Rakefile
You can configure some or all of your CloudFoundry details when calling
require 'cf-deploy' CF::Deploy.rake_tasks! do api 'api.run.pivotal.io' username 'firstname.lastname@example.org' password 'SOMETHING' organisation 'Made' space 'development' environment staging: 'assets:precompile' environment production: 'assets:precompile' do route 'yourwebsite.com', 'www', flip: true end end
All are optional. If you do not provide any you will be prompted when running the rake tasks.
Defining CloudFoundry details using ENV variables
Instead of defining your CloudFoundry login details in your Rakefile and committing them to your code repository you can instead provide them using ENV variables on your command line:
export CF_API=api.run.pivotal.io export CF_USERNAMEemail@example.com export CF_PASSWORD=SOMETHING export CF_ORG=Made export CF_SPACE=development
Now you can run any of the
cf-deploy rake tasks providing you have called
CF::Deploy.rake_tasks! in your
Deploying an environment
If you defined a staging environment in your Rakefile the following task will have been created:
bundle exec rake cf:deploy:staging
Run this to deploy out your staging environment.
Any environment you define will have a task created named
Deploy the next blue/green environment
If you have defined CloudFoundry manifest files matching
manifests/*_green.yml you will be able to call
rake cf:deploy:* without
_green. For example with
production_green.yml you can call the following:
bundle exec rake cf:deploy:production
Running the deploy task for an env with blue and green manifests will trigger a lookup to see which env is currently deployed. The task will then start deploying the other production color, so if green is currently deployed then blue will be deployed. If neither is currently deployed, blue will be deployed first.
Once deployed your routing will still be pointing to the previous deployment. If you run the same task again, the same environment will be deployed. That is if green was deployed, and then you run the task, blue will be deployed, if you run the task again, blue will be deployed again. This is because we work out the current deployment based on where your routes are pointing and since the deploy command for blue green environments doesn't map routes the current deployment will not change.
First time proviso
This isn't the case for a first time deploy. The first time you deploy your blue environment will be deployed and any defined routes will be mapped to all apps defined in your blue manifest.
Switch routes over to new environment
In order to flip your routes from blue to green or vice-versa you need to run the following task.
bundle exec rake cf:deploy:production:flip
This will go ahead and map routes to whatever color the routes aren't mapped to and then unmap the other color. At this point your new production will be deployed and live.
Turn off idle app
Once your new production has been flipped you may want to turn off your idle application. There is a task for this too:
bundle exec rake cf:deploy:production:stop_idle
Developed and maintained by Made Tech. Key contributions:
Copyright © 2014 Made Tech Ltd. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.