Back to Posts List


Deploying Ruby on Rails on EC2 - Using Rubber

A while ago i wrote a post tutoring a deployment of a simple rails application on ec2 using the EC2onRails gem,
in this post i will explain how to use another plugin, called rubber that simplifies the deployment of more complex applications, those with multiple instances for example.

Setting the other stuff we need

Follow this section on my previous Rails on EC2 post to get your EC2 account SSH keypair first,
Then, install he amazon-ec2 gem:

$ sudo gem install amazon-ec2

the AWS::S3 gem:

$ sudo gem install aws-s3

Our beloved Capistrano:

$ sudo gem install capistrano

and the nettica gem:

$ sudo gem install nettica

note that you only need to install the nettica gem if you need to automatically map specific instances to A Records.

Setup Your Application

in your application root, install the rubber plugin:

$ script/plugin install git://

Generating Configuration

and than the crazy part, you’ll have to generate a rubber deployment setup that matches your application needs. To do that you’ll have to choose on your own.
Each one of these “configurations” contains one or more service that is needed for your application, such as Apache, Mysql, Sphinx and more, and some act as bundles that basically install a group
of other services:

  • apache: Installs apache
  • base: configuration needed by all other packages/services you must install this one anyway.
  • complete_mysql:
    • minimal_mysql
    • monit
    • munin
    • memcached
  • complete_passenger_mysql:
    • base
    • mysql
    • apache
    • passenger
    • munin
    • memcached
  • cruise: the cruise-control (CI server).
  • haproxy: the haproxy module.
  • memcached: the memcached module
  • minimal_mysql:
    • base
    • mysql
    • mongrel
    • nginx
    • haprox
  • minimal_nodb:
    • base
    • mongrel
    • nginx
    • haproxy
  • mongrel: the mongrel cluster application server
  • monit
  • munin
  • mysql
  • mysql_cluster
  • mysql_proxy
  • nginx
  • passenger
  • sphinx

The one that we will use is the one that was the most suitable for my application, the complete_passenger_mysql, so in your project root type:

$ script/generate vulcanize complete_passenger_mysql

Configuration Files

now edit your config/rubber/rubber.yml and add your access_key, secret_access_key, aws_account, ec2_key_name and ec2_key_file (you can get all of those by following my previous post).
each service/bundle installs with a set configuration files, a rubber-module.yml file for configuring each module will be found in your config/rubber folder, a long side a deploy-module.rb file for deployment specific behavior.

As you can see, the configuration files are basically ERB templates.
Some special variables are defined to handle and control the module:

Variable Description
@*path* The output path to write the transformed config file to
@*read_cmd* The command to use for reading the original config file from, e.g. “crontab -l”
@*write_cmd* The command to use for piping the transformed config file to, e.g. “crontab -”
@post The command to run after generating the config file ONLY if it has changed
@owner The owner the output file should have, e.g. “root”
@group The group the output file should have, e.g. “system”
@perms The permissions the output file should have, e.g. 0644
@additive Sets transformation to be additive, only replaces between given delimiters, e.g. @additive = [“## start”, “## end”]

The variables set in bold are those you must supply.
In addition, within the configuration files you can access to the rubber configuration objects rubber_env (rubber*.yml) and rubber_instances (instance*.yml).

to test your configuration run:

$ rake rubber:config

this will apply your configuration to your development environment, so you can check that everything is up and running.
note that:

  1. Configuration files that exist in config/rubber/common will be transformed for all hosts.
  2. Configuration files that exist in config/rubber/role/ will only be transformed on the hosts that are members of role_name.
  3. Configuration files that exist in config/rubber/host/ will only be transformed on the hosts with a hostname of host_name.

and will override based on that order in favor of the most specific configuration and alphabet order of configuration files.

Bootstrap and Deploy

first, you’ll need to create your environment bootstrap, in this case, it’s production production:

$ ALIAS=production ROLES=web,haproxy,app,mysql_master,passenger cap rubber:create

Note that this is a simple deployment, to use a little bit more complex deployment use something like:

$ ALIAS=web01 ROLES=web,haproxy, passenger cap rubber:create
$ ALIAS=app01 ROLES=app cap rubber:create
$ ALIAS=app02 ROLES=app cap rubber:create
$ ALIAS=db01 ROLES=mysql_master cap rubber:create
$ ALIAS=db02 ROLES=mysql_slave cap rubber:create

after you finished setting up your Rubber configuration, it’s time to create the bootstrap:

$ cap rubber:bootstrap

and then just the regular capistrano deployment fire starters:

$ cap deploy:check
$ cap deploy:setup
$ cap deploy:cold

and that’s about it.

A Final Note

The process of configuring an instance, bootstarping, and delpoying will run on all the instances your have specified, old and new!, so you shoudl always check your configuration on a local/staging environment.


blog comments powered by Disqus

I Don't have cookies.


Variable Value
{ '' => [ '#rubyonrails', '#railsbridge', '#ruby', '#mootools' ]}

You're seeing this error because I think it is funny.