views:

918

answers:

5

I'm working on upgrading one of our Rails 2.3.8 apps to Rails 3, and have run into an annoying problem with bundler and deployment. I develop the application on a Windows machine, but the production environment is running Ubuntu Linux. Now, my problem is that bundler is ignoring the mysql gem in the production environment, and Passenger spits out: "!!! Missing the mysql gem. Add it to your Gemfile: gem 'mysql', '2.8.1'"

Here is my Gemfile:

# Edit this Gemfile to bundle your application's dependencies.
# This preamble is the current preamble for Rails 3 apps; edit as needed.
source 'http://rubygems.org'

gem 'rails', '3.0.0'
gem 'net-ldap', :require => 'net/ldap'
gem 'highline', :require => 'highline/import'
gem 'mysql', '2.8.1'
gem 'net-ssh', :require => 'net/ssh'

# Bundle gems for the local environment. Make sure to
# put test-only gems in this group so their generators
# and rake tasks are available in development mode:
group :development, :test do
  gem 'fakeweb', :require => 'fakeweb'
  gem 'flexmock', :require => 'flexmock/test_unit'
end

As you can see, the mysql gem is specified. However, when deploying, bundler ignores it. Why? The reason is that Bundler generates the following Gemfile.lock (only relevant parts included):

....
mime-types (1.16)
mysql (2.8.1-x86-mingw32)
net-ldap (0.1.1)
....

Notice that it includes the platform specific gem. This is obviously NOT what I want it to do, as that gem is not suitable (and appearently ignored) when running under Linux.

So, does Bundler come with any way to deal with these issues? Or do I have to remember to manually change the mysql gem version in the generated Gemfile.lock every time I run bundle install on my development machine?

Thank you in advance!

Update

It seems like the bundler team is aware of this issue.

+1  A: 

Don't commit Gemfile.lock and your gems to production. You have to run bundler install again in production.

jpartogi
Well, we ARE recommended to put our ``Gemgile.lock`` into version control. And bundler requires this file when using the --deploy flag.
Daniel Abrahamsson
Committing `Gemfile.lock` will lock you in to the gems listed in `Gemfile.lock`. `Gemfile` itself is enough to define the gems that are needed for your apps.
jpartogi
A Gemfile with no Gemfile.lock is only good enough until you have a conflict down your tree of dependent gems. If you're using more than a handful of gems, then you're likely to have conflicts sooner or later. Also, if you don't check in your Gemfile.lock, you cannot be sure that you're using the exact same gems on every machine (unless you only declare strict dependencies in your Gemfile, which makes it a pain to maintain). Basically, by not checking in Gemfile.lock, you're dumping the two main reasons to use bundler instead of, say, a batch file that installs a bunch of gems.
Paolo Perrotta
A: 

You can do something like this:

platforms :ruby do
  gem "sqlite3-ruby", :require => "sqlite3", :group => [:development, :test]
end

platforms :jruby do
  gem 'activerecord-jdbc-adapter', :require => false
  gem "jdbc-sqlite3", :require => false
end

Btw, you should put your Gemfile.lock into the version control because this way all machines will run the application with the same gems versions.

Diego Carrion