Bit of Background
One of the new bits of technology coming into Rails 3.0 is the all singing and dancing Gem Bundler . If you’ve ever found yourself in config.gem hell, or have pushed a perfectly fine project from development to production and it’s all gone kaput due to gem problems, than this is the medicine that you need. Here’s the blurb
Bundler is a tool that manages gem dependencies for your ruby application. It takes a gem manifest file and is able to fetch, download, and install the gems and all child dependencies specified in this manifest. It can manage any update to the gem manifest file and update the bundled gems accordingly. It also lets you run any ruby code in context of the bundled gem environment.
We’re not running Rail 3.0 yet, but thats no reason not to start using bundler.
Let’s install it, I’ve settled on version 0.7.1 as I was having odd problems with any of the newer versions.
sudo gem install bundler -v 0.7.1
Next step is to create a file called Gemfile in your applications root directory, and then subsequently fill it with what gems you need, and also in that environments you need them. Here’s the one I’m using.
Now add these lines to your .gitignore file, this will make deploys easier and faster
bin/ vendor/bundler_gems/* !vendor/bundler_gems/cache/*
Now it’s time to start a bundling. From inside your application run
That will now do all it’s magical stuff for you, creating the bin executables and the necessary files and folder in the vendor/bundler_gems folder.
Will it work yet? Not quite 🙁
To get it working with rails 2.3.4 I had to do the following things.
1. Create a file called config/preinitializer.rb with this code in
2. Add the following line to all environment files, ie, config/environments/*.rb
Now when I start my app using script/server, or nginx and passenger it all works as it should. I even removed all my local gems just to check. (stupid idea as not all my rails projects are bundled yet :-))
Deploying the medicine
I’ve unashamedly knicked the deploy stuff from numerous people, I love you all, even though I can’t remember your names.
Watch out for….
It might sound obvious but some gems can’t be handled in this way. Have a good think about that prior to using bundler, one for us was passenger. I had a hell of a time trying to workout how to use it with bundler, than I got some sane advice to just install passenger as a module of nginx, problem gone. The unicorn is stalking me at the moment though, so we may have a passenger who wants to get off shortly.
We were using REE in production, in my experience REE and bundler didn’t get on, so I had to remove all REE and install the ruby that comes down the pipe with aptitude, then rebuild nginx with passenger module after doing that, it all worked ok then.
I now deploy from the application like so
./bin/cap staging/production deploy
That way I know what version of capistrano I’m using per app
Don’t delete all your local gems until all your projects are bundled, and even then be careful.
If you have rake tasks that are being run by cronjobs, make sure that the rake you are accessing is present.
RAILS_ENV=production rake some:jobname will not work from a cron job now, as rake is not available like that any more. You’ll need to edit it to point at the rake in your project bin.
RAILS_ENV=production /path/to/project/bin/rake some:jobname
Or add the bin folder in your project path to your $PATH, that might be a better solution.
Happy bundling everyone.
Our Current Technology
ubuntu 8.04, rails 2.3.4, ruby 1.8.6, nginx 0.7.64 (with passenger 2.2.8 installed as a module)
People who’ve helped immeasurably
#carlhuda on freenode