Yehuda Katz is a member of the Ruby on Rails core team, and lead developer of the Merb project. He is a member of the jQuery Core Team, and a core contributor to DataMapper. He contributes to many open source projects, like Rubinius and Johnson, and works on some he created himself, like Thor.
Using Bundler in Real Life
February 9th, 2010
A lot of people have asked me what the recommended workflows for bundler are. Turns out, they’re quite simple.
Let’s step through a few use-cases.
You Get a Repo for the First Time
You’ve just checked out a git (or other) repository for an application that uses bundler. Regardless of any other features of bundler in use, just run:
bundle install
This will resolve all dependencies and install the ones that aren’t already installed in system gems or in your system’s bundler cache.
You Update a Repo Using Bundler
If you update a repository using bundler, and it has updated its dependencies in the Gemfile, regardless of any other features in use, just run:
bundle install
As above, this will resolve all dependencies and install any gems that are not already installed.
You have created a new Rails application
If you’ve created a new Rails application, go inside it and run:
bundle install
This will make sure that Rails’ dependencies (such as SQLite3) are available in system gems or your system’s bundler cache. In most cases, this will not need to install anything.
To check whether your system already satisfied the application’s dependencies, run:
bundle check
As you work in the application, you may wish to add dependencies. To do so, update the Gemfile, and run:
bundle install
You are ready to share your new Rails application
Now that you have a working Rails application, and wish to share, you might wish to ensure that your collaborators get the same versions of the gems as you have. For instance, if webrat specified “nokogiri >= 1.4″ as a dependency, you might want to ensure that an update to nokogiri does not change the actual gems that bundle install will install.
To achieve this, run:
bundle lock
This will create a new file called Gemfile.lock in your root directory that contains the dependencies that you specified, as well as the fully resolved dependency graph. Check that file into source control.
When your collaborators receive the repository and run bundle install, bundler will use the resolved dependencies in Gemfile.lock.
You have a locked application, and wish to add a new dependency
If you add a new dependency to your Gemfile in a locked application, Bundler will give you an error if you try to perform any operations.
You will want to run bundle unlock to remove the lock, then bundle install to ensure that the new dependencies are installed on your system, and finally bundle lock again to relock your application to the new dependencies.
We will add a command in a near-future version to perform all these steps for you (something like bundle install –relock).
You want a self-contained application
In many cases, it is desirable to be able to have a self-contained application that you can share with others which contains all of the required gems.
In addition to a general desire to remove a dependency on Gemcutter, you might have dependencies on gems that are not on a publicly accessible gem repository.
To collect up all gems and place them into your app, run:
bundle pack
When running bundle install in the future, Bundler will use packed gems, if available, in preference to gems available in other sources.
Conclusion
I hope these workflows have clarified the intent of Bundler 0.9 (and 1.0). During our work on earlier versions, the lack of these workflows came up again and again as a source of frustration. This was the primary reason for the big changes in 0.9, so I hope you find them useful.

moonmaster9000, Posted February 9, 2010, 8:03 am
thanks yehuda! looking forward to simplified gem management.
i’m curious: does bundle pack also pack in the compiled native extensions that go along with a gem?
Christoph Olszowka, Posted February 9, 2010, 8:07 am
Thanks for clearing things up! I’ve been wondering for ever how bundle pack handles C-extension gems – is the source code kept around? If so, when does compiling happen? If not, what to do with those gems in bundler?
nnc, Posted February 9, 2010, 8:35 am
Thanks Yehuda! I found this post to be a great overview of what can Bundler do for me, which is exactly what I was looking for.
trevor, Posted February 9, 2010, 9:35 am
i’m seeing this error with
bundle pack:runtime.rb:109:in `basename’: can’t convert nil into String )
all other commands seem to work.
% rails -v Rails 3.0.0.beta % ruby -v ruby 1.9.2dev (2010-02-03 trunk 26544) [x86_64-darwin10.2.0] % rails myapp % cd myapp % bundle pack Copying .gem files into vendor/cache * text-hyphen-1.0.0.gem * abstract-1.0.0.gem * text-format-1.0.0.gem * erubis-2.6.5.gem * builder-2.1.2.gem * mime-types-1.16.gem * sqlite3-ruby-1.2.5.gem * memcache-client-1.7.8.gem * i18n-0.3.3.gem /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/runtime.rb:109:in `basename': can't convert nil into String ) from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/runtime.rb:109:in `block in pack' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/runtime.rb:105:in `each' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/runtime.rb:105:in `pack' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/cli.rb:90:in `pack' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor/task.rb:32:in `run' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor/invocation.rb:108:in `block in invo' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor/invocation.rb:115:in `call' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor/invocation.rb:115:in `invoke' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor.rb:137:in `block in start' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor/base.rb:369:in `start' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/lib/bundler/vendor/thor.rb:124:in `start' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-0.9.3/bin/bundle:4:in `' from /usr/local/bin/bundle:19:in `load' from /usr/local/bin/bundle:19:in `'JGeiger, Posted February 9, 2010, 9:46 am
I’m glad to see the possible addition of the bundle install –relock option. It’s not to hard to do the other way, but one command is better than three. Is there or will there be a command like bundle pack –prune so the old gems in the cache can be deleted? I know I’ve run into this already.
Also, is there an upgrade path/procedure for people using bundler 0.8.1 and rails 2.3.x to transition to bundler 0.9->1.0?
Sikachu!, Posted February 9, 2010, 9:59 am
After I use Bundler for new project and Rails, I can only tell that THIS is really the thing we want for gem dependency!
Really, really nice one!
Next: rewrite rubygems system? :P
Doug Barth, Posted February 9, 2010, 10:13 am
Thanks for the use case run down. The UI is a lot clearer than earlier versions.
One use case I’m unsure of is dependencies in a Rubygem. Should they use bundler? How does that fit with a Gemspec?
Aaron Gibralter, Posted February 9, 2010, 11:08 am
Any plans to include –list-outdated?
BJ Neilsen, Posted February 9, 2010, 11:11 am
Really really digging Bundler, great work so far. I was wondering why I don’t get a .bundle directory until I lock the bundle. This didn’t make much sense to me since I’m requiring the .bundle/environment file in my application startup.
Sven Fuchs, Posted February 9, 2010, 12:08 pm
Could you add some scenario about how Bundler could help with gem development?
E.g. suppose I have a clone of ActiveModel, I18n and maybe additional gems on my disk. Now I’m working on a plugin targeting ActiveModel but also relying on I18n. I want each of the gems to use my local repository clones so I can easily go in there for debugging or maybe even tweaking things. But in order to keep this maintainable and share-able I obviously don’t want to mess with my gems setup manually (e.g. symlinking directories) or even hardcode filesystem paths. Oh, and ideally I’d want to be able to run particular parts of the AMo test suite from within my plugin’s test suite so I can ensure I don’t break the API.
Is this something Bundler can help me with? I suppose it’s a scenario that you guys eat deal with every day :)
Thanks :)
Donovan Bray, Posted February 9, 2010, 12:22 pm
@trever, I had the same error message.
I had originally specified a bundle_path of vendor/bundler_gems in my Gemfile. I remmed it out, and rm -rf vendor/bundler_gems.
Then did “bundle install vendor/bundler_gems”.
“bundle pack” then worked without error. They key to get rid of the error was to rm -rf the old structure.
I think it has something to do with the relative path.
rubiii, Posted February 9, 2010, 3:56 pm
BJ Neilsen: you need to change your preinitializer to: http://gist.github.com/298545#file_preinitializer.rb
Scott Bronson, Posted February 9, 2010, 10:15 pm
Won’t bundle unlock; bundle lock update ALL gems in my project to the latest gems on my system? Seems a bit scarier of an operation than you imply.
Bundler rocks BTW. Handling gems in complex Rails apps used to be a real problem.
Christiaan, Posted February 10, 2010, 6:43 am
@SvenFuchs This I would like to know also.
Larry Sprock, Posted February 10, 2010, 6:21 pm
No amount of hackery or tom foolery has made it work for me in rails 2.3.x on a fresh app or otherwise… So seems there is still much work to be done before 1.0. I was and will continue to use 0.8.1 until then.
UnderpantsGnome, Posted February 11, 2010, 9:49 am
@sven, @christian – rvm may be able to help you with this scenario to some extent. If not out of the box and you can make a decent case for it Wayne would probably help you get it added. He’s been tremendously helpful.
http://rvm.beginrescueend.com/
mgutz, Posted February 15, 2010, 4:11 pm
Is there any talk of integrating Bundler into rubygems? Using a Gemfile instead of .gemspec for dependencies would provide consistency when creating either an app or a gem. IMHO, Bundler is gem++.
gem check –gemfile
gem install –gemfile
…
Brad Gessler, Posted February 16, 2010, 2:48 pm
Hey folks, Brad from Poll Everywhere here. We’re upgrading to bundler 0.9.5 and ran into a questions using Bundler with git.
First, should the .bundle folder be ignored? If so, there is an issue when another developer pulls a project and runs ‘bundle install’. The bundler gets to the end of the install process and blows up because .bundle/environment.rb is not found. The error messaging isn’t very clear around this problem either, but a ‘bundle lock’ command fixes it since the generates the .bundle folder. I’m positive that .bundle should be ignored in .git because it contains absolute paths to the gem files, so the bundle install command should probably generate this file if its not present.
Joe Van Dyk, Posted February 16, 2010, 6:10 pm
Is there a recommended way to deploy apps that use bundler? Hopefully bundler 1.0 will come with some capistrano recipes or something.
John Lauck, Posted February 17, 2010, 10:00 pm
Similar to @BradGessler’s question: How do you handle multiple developers working on a project? It seems common that developers could use different gems in their dev environments. Database systems are the first that come to mind. Some developer might use sqlite while another uses mysql.
todd, Posted February 24, 2010, 8:00 am
when i “bundle install –disable-shared-gems” All the gems are installed from system gems, shouldn’t this force the gem repo into my application… the concern is having to rely on the environment for things like
which unicorn_rails
where as before it could be known that unicorn_rails would always be in the APP_ROOT/bin
Make sense?
cec, Posted May 6, 2011, 10:18 am
Hi, thank you for this post about workflows with bundler!
However, I’m missing how to deal with locking when deploying in situations where some gems are in the development group, but not in the production group and vice-versa.
After deploying the app with capistrano, I find myself connecting to my production box, removing the gemfile.lock and running bundle install –without development.
Given how sharp and clear the organization of your projects is, I’m certain that I’m missing some fundamental concepts…