Bundler: Quicker Deployments With Shared Bundle

Often when you deploy your app, there are gems that need some native code or gems that need root permissions to be installed into default locations. In most cases you don’t have them or don’t want to use them to be sure the deployment is perfectly “sandboxed”.

Bundler 1.0 solves this problem by introducing the “–deployment” key. When specified during the bundle installation, Bundler creates a “vendor/bundle” directory and places all your gems in it effectively isolating them from the outside environment. Since you own the app directory, there’s no issue with permissions. The downside of the approach is that every time you deploy the application the directory either doesn’t exist or empty and you have to install the same gems over and over. Takes time and space.

Fortunately, that’s easy to fix by linking “vendor/bundle” to a shared location right before running “bundle install –deployment”. Here’s how I do it in my Capistrano deployment script:

task :bundle_gems, :roles => :app do
  run "mkdir -p #{shared_path}/bundle && ln -s #{shared_path}/bundle #{release_path}/vendor/bundle"
  run "cd #{latest_release}; bundle install --deployment --without development test"