-
Notifications
You must be signed in to change notification settings - Fork 247
Note that capistrano needs both a public and private key file in the same directory in order to connect when setting the rubber config option for ec2_key_file (which should point to the private key file). You should have got the private key when you created a ec2 keypair during the ec2 install/setup (See Requirements). You can get the public key in one of two ways:
- Create the public key from the private key: ssh-keygen -y -f gsg-keypair > gsg-keypair.pub
- Create an instance and ssh into it to grab the file at ~ubuntu/.ssh/authorized_keys (or /mnt/openssh_id.pub for older alestic AMIs)
Alternatively, one can leave ec2_key_file unset and use ssh-add or edit ~/.ssh/config to add your ec2 key to the set used to authenticate with.
What does your cloud_providers → aws → key_file look like in rubber.yml? The default is:
key_file: “#{Dir[(File.expand_path(‘~’) rescue ‘/root’) + ‘/.ec2/*’ + cloud_providers.aws.key_name].first}”
Which would not match a keyfile that ends in a .pem extension.
Another problem I’ve seen is for people that have many keys in their ssh-agent. By default, an ubuntu instance only allows a few attempts before failing, so if you have many keys, it tries them serially and will fail before reaching the right one. You can clear out your keys with “ssh-add -D”
Running “cap rubber:create” with add to the instance-`.yml a structure with the roles and information about the newly created instance. This file, however, needs to be updated on your SCM if that’s the configured deploy method. Failing to do that will have a local instance-`.yml version that differs from the one on the host, bringing the “Host XXX is not found”. To fix it, just commit and update your SCM version with the changes on the file.
Rubber is fairly separated from the app itself, so you could reuse its instance-*.yml and configuration files for setting up your other app.
First, make sure the second app is Capistrano ready and using a Gemfile, where you’d add the Rubber gem. The next step is to initialize Rubber but setting its root to your other app’s location. That will bring all of Rubber goodness to the next codebase reusing your already tested configuration. You can accomplish this by updating your Capfile like this:
load 'deploy'
# Uncomment if you are using Rails' asset pipeline
# load 'deploy/assets'
#*** STARTS RUBBER CONFIGURATION
env = ENV['RUBBER_ENV'] ||= (ENV['RAILS_ENV'] || 'production')
# Adjust this line to fit your main app location. The line below would create a "../other_app" one.
root = File.expand_path(File.dirname(__FILE__) + '/../other_app')
# this tries first as a rails plugin then as a gem
require 'rubber'
Rubber::initialize(root, env)
require 'rubber/capistrano'
#*** FINISHES RUBBER CONFIGURATION
load 'config/deploy' # remove this line to skip loading any of the default tasks
Next, you need to setup your config/deploy.rb to bring the Rubber tasks. You could start by copying the contents that make sense from your main app’s config/deploy.rb. Is certainly possible to copy the same code but make sure it complies to your needs. Be sure to set up your “application” and “deploy_to” to the values that refer to this second app since they are the ones that Rubber will use to create the folder structure.
Due to the way rubber loads instance data when transforming configuration files during a deploy, you will need to either select cloud storage or cloud table storage as your instance_storage in rubber.yml. In your secondary app, be sure to configure this variable to be the exact same as the variable in your main app. You will also want to configure the following variables in your secondary app’s rubber.yml:
- app_name
- cloud_providers/aws/access_key
- cloud_providers/aws/secret_access_key
- cloud_providers/aws/account
- cloud_providers/aws/backup_bucket
After that, you could just “cap rubber:bootstrap” to setup the main folder structure and then the regular “cap deploy”. All FILTER and FILTER_ROLES will work as expected, reusing any nodes you’d already created.
Be sure to configure your Web servers conf files to point to this second app structure so it’ll be replicated on each instance you need.
Rubber has been built to allow multiple types of configurations. It’s fairly common to start with a complete_* template and then another one in top of it that suits your needs (memcached for example). To accomplish this, you could follow this set of instructions:
First, add the new configuration files to your app
rubber vulcanize OTHER_TEMPLATE
Next, if you’ve already created some instances and want to add new roles to them, there’s a handy task that accomplishes that:
cap rubber:add_role
It’ll ask for your alias name and which roles to add. This will update your instance-`*.yml file with the new structure.
Now you just need to instruct Rubber to upload and update the new configuration files by bootstrapping your needed instances:
cap rubber:bootstrap
Rubber sets up RUBBER_CONFIG/RUBBER_INSTANCE global variables within a rails initializer. If installed as a gem, you’ll need to add a “config.gem ‘rubber’” to get the initializer to load. See Configuration for more details.
Often this is a net-ssh timeout. Your first course of action is to try resuming the create command a few times with the following:
ALIAS=web01 cap rubber:refresh
FILTER=host cap rubber:bootstrap
cap deploy
→ Replace web01 with the instance alias you gave your app.
If this fails you may have an issue with your SSH keys. If Amazon produced a key for you called disney-key.pem, rename this to disney-key, place it in ~/.ec2/ and, within that same directory, generate a disney-key.pub with your public key.
First ensure that your credentials are correct. If that’s not the problem, you’re most likely receiving a 404 because you don’t have a bulk DNS account You’ll need to purchase one to use the web services API.
If you can’t tweak rubber to meet your needs, then there are alternatives:
- Free
- Commercial
For the free alternatives, aside from poolparty, the main difference to rubber is that rubber was built from the ground-up to support deploying to multiple instances, and has a very flexible mechanism for configuring said instances at a host, role or global level.
- cloudkick is a commercial but free web monitoring/management service for ec2 instances.
First, checkout your fork of rubber. Then, in your Gemfile, specify the `:path` option like this to use your local repository:
gem "rubber", :path => "/path/to/rubber"
If you run `cap`, make sure to use `bundle exec`
bundle exec cap rubber:create
Rubber can be installed in vendor/plugins instead of as a gem. You can do this as a git submodule to your rubber fork, or by just copying it in. I typically create a dummy rails project and symlink its vendor/plugins/rubber to my local rubber repository. Here is the rails template I use for creating the dummy rails project. Create the dummy project with a command like: “rails -d mysql -m rubber-dev-rails-template.rb rubbertest” after editing the template for your needs.
If you don’t want a task to happen globally, you can limit the scope by use of the FILTER or FILTER_ROLES environment variables. You can use both at the same time, and they both support negation, so that you can do something like deploy to all hosts in the worker role except worker03. They also both support ranges of hosts, though it usually only makes sense for FILTER, e.g. FILTER=worker01~worker03 to operate on those three machines, or FILTER=worker01~worker50,-worker05~-worker08 to operate on 1-50 excluding 5-8
For Example:
Say you have the following hosts/roles:
host1 => role1
host2 => role1
host3 => role2
host4 => role2
To run just to host1 and host2:
cap deploy FILTER=host1,host2
All hosts except host1:
cap deploy FILTER=-host1
To host3, host4:
cap deploy FILTER_ROLES=role2
To host1, host2:
cap deploy FILTER_ROLES=-role2
(Note the ‘-’ in front or ‘role2’ in order to denote exclusion.)
To host2:
cap deploy FILTER_ROLES=role1 FILTER=-host1
FILTER will work for limiting any rubber/capistrano task, and takes a csv list of aliases to filter that task for, as well as any tasks that end up getting called by that task. Note that this is not the same as the standard filtering provided by capistrano with the HOSTS/ROLES env variables. In the cap case, it actually forces all tasks, regardless of the role specified for them, to run on the given hosts/roles. In the rubber/filter case, the only tasks that are run are those with roles/hosts that match the given filter.
Seems to be actual for rubber 1.13.0
My case:
cap RUBBER_ENV=staging deploy:cold
output:
- executing “cd /mnt/app-staging/releases/20110506104005; rake RAILS_ENV=staging db:migrate”
servers: [“staging.app.com”]
[staging.app.com] executing command- [out :: staging.app.com] (in /mnt/app-staging/releases/20110506104005)
- [out :: staging.app.com] rake aborted!
- [out :: staging.app.com] !!! Missing the mysql2 gem. Add it to your Gemfile: gem ‘mysql2’
- [out :: staging.app.com]
That is bundler issue. Solution worker for me:
https://github.com/carlhuda/bundler/issues/894
When you see this error add the following lines to boot.rb file (if its a rails environment)
require ‘yaml’
YAML::ENGINE.yamler= ‘syck’
For more information pelase refer to question at stackoverflow