Skip to content

Running with vagrant

chetstone edited this page Jul 19, 2014 · 13 revisions

Running with Vagrant

Starting with Rubber 2.5.0 it's now possible to use Rubber as a Vagrant provisioner. This means your can test out your Rubber configuration in locally created clusters before going live on a remote cloud service. Testing locally can often be faster and far cheaper than invoking a remote staging server.

Installing the Plugin

In order to use the Rubber provisioner, you need to first install the Rubber plugin for Vagrant like so:

$ vagrant plugin install rubber

To verify the plugin installed correctly, you can run:

$ vagrant plugin list

You should see an entry for 'rubber' along with the version number. Note that there's no requirement to keep this in sync with the version of Rubber you're using in your project. However, if there are improvements or bug fixes made to the Vagrant hooks, you'll need to update the plugin. Updating the plugin works the same way as installing it. Just run vagrant plugin install rubber again.

Configuring Rubber in your Vagrantfile

We try to provider sane defaults for everything. If you don't configure anything, by default Rubber will run in the 'vagrant' RUBBER_ENV/RAILS_ENV and will configure your instance to whatever you have set up for the staging_roles value in your project's base Rubber configuration. However, if you'd like to customize your configuration, you can.

The simplest configuration is for a single VM. In that case, you can configure Rubber at a top level in your Vagrantfile (run vagrant init first to generate a Vagrantfile for your project, see Vagrant Getting Started for details):

config.vm.network :private_network, ip: "192.168.70.10"

config.vm.provision :rubber do |rubber|
  rubber.rubber_env = 'vagrant'

  # If you remove this line, the configured staging_roles will be used instead.
  rubber.roles = 'postgresql_master,db:primary=true'
  
  # Only necessary if you use RVM locally.
  rubber.rvm_ruby_version = 'jruby-1.7.4'
end

You can also configure Rubber for a multi-VM setup. In this case, you need to configure Rubber on a per-VM basis. This does mean you'll end up with some configuration that appears to be duplicate, like setting rubber_env for each host. But that's because there's no way to merge a top-level config with a per-VM config. This does free you up to configure multiple VMs in different environments however. A two node cluster configuration might look like:

config.vm.define :db do |db|
  db.vm.network :private_network, ip: "192.168.70.10"

  db.vm.provision :rubber do |rubber|
    rubber.rubber_env = 'staging'
    rubber.roles = 'postgresql_master,db:primary=true'
  end
end

config.vm.define :web do |web|
  web.vm.network :private_network, ip: "192.168.70.11"

  web.vm.provision :rubber do |rubber|
    rubber.rubber_env = 'staging'
    rubber.roles = 'web,app'
  end
end

NB: Rubber requires a private network to be configured for your VMs. We do not support the older hostonly format.

Configuring Rubber

Rubber includes a vagrant cloud provider that must be configured for your environment. We generate a default environment override file when you rubber vulcanize base that handles the default of case of the Rubber environment being named 'vagrant'. You can see this config in config/rubber/rubber-vagrant-env.yml.

If none of that made sense, you may want to read up on Rubber providers.

SSH key_file

As part of vulcanize, rubber will configure the vagrant environment to use the default generated vagrant ssh key in config/rubber/rubber-vagrant-env.yml:

cloud_providers:
  vagrant:
    key_name: insecure_private_key
    key_file: '~/.vagrant.d/insecure_private_key'

Rails Environment

Since Rubber runs with RUBBER_ENV/RAILS_ENV = 'vagrant', you probably want to set up a rails environment file to run on Vagrant:

cp config/environments/production.rb config/environments/vagrant.rb

Operation

Once your configuration is set up, you can start your cluster simply with:

$ vagrant up

This will create your VMs and hook into Rubber so Rubber can bootstrap and deploy to the machines. Once started, you can use Rubber to control and deploy to your cluster. You're free to use the other Vagrant commands directly, but doing so may cause your instance file to fall out of date with Rubber due to limitations of the Vagrant provisioner API and what events we can hook into. Where possible we synced Vagrant commands with the corresponding Rubber tasks.

If you have rubber >= 2.5.5 and Vagrant >= 1.3.0, you can stop your cluster with:

$ vagrant destroy

Older versions of Vagrant didn't support shutdown hooks for provisioners, so vagrant destroy would destroy the VM, but keep all the rubber state around. In those cases, cap rubber:destroy would be a better option as it will clean up rubber state and destroy the VM.

Some Gotcha

If you keep your vagrant machine up during sleep (or whatever the reason)
The time system time in it becomes incorrect
And when you are using anything related to Amazon S3 (like asset_sync)
It will return RequestTimeTooSkewed error

This is caused by incorrect system time with S3 server
So you need to restart by using

$ vagrant reload [optional machine name]

I assume you have ntpd installed, no?

Some related articles: