Home Articles

使捆绑器为不同的平台使用不同的宝石

Asked
Viewed 1436 times
45

我正在努力将我们的一个Rails 2.3.8应用程序升级到Rails 3,并且遇到了捆绑和部署的恼人问题 . 我在Windows机器上开发应用程序,但 生产环境 环境正在运行Ubuntu Linux . 现在,我的问题是Bundler忽略了 生产环境 环境中的 mysql gem,并且Passenger吐出: "!!! Missing the mysql gem. Add it to your Gemfile: gem 'mysql', '2.8.1'"

这是我的 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

如您所见,指定了 mysql gem . 但是,在部署时,bundler会忽略它 . 为什么?原因是Bundler生成以下 Gemfile.lock (仅包括相关部分):

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

请注意,它包含特定于平台的gem . 这显然不是我想要它做的,因为在Linux下运行时,gem不适合(并且显然被忽略) .

那么,Bundler是否有办法解决这些问题?或者我必须记得每次在我的开发机器上运行bundle install时,在生成的 Gemfile.lock 中手动更改mysql gem版本?

先感谢您!

Update

似乎捆绑团队知道这个issue .

9 Answers

  • 37

    不要将 Gemfile.lock 和您的宝石提交给 生产环境 . 你必须在 生产环境 中再次运行 bundler install .

  • 8

    我有一个类似的问题 . 我希望能够在我的Gemfile中写出这样的东西:

    platforms :ruby do                      # linux
      gem 'nokogiri', "1.5.0.beta.2" 
    end
    
    platforms :mswin do
      gem 'nokogiri', "1.4.4.1" 
    end
    

    但是,捆绑者告诉我,我不被允许 . 因此,我的解决方法,在这个特定情况下工作是指出一系列版本:

    gem 'nokogiri', ">= 1.4.4.1", "<=1.5.0.beta.2"
    

    目前 - 在我的Windows计算机上提供1.4.4.1版本,在我的Linux计算机上提供1.5.0.beta.2 . 也许你有可能写一个类似的丑陋的解决方法;-)

  • 5

    我遇到了这个问题,最后为这个痛苦的任务编写了脚本 . http://gouravtiwari.blogspot.com/2011/03/development-on-windows-deploying-to.html

  • 2

    这是known issue in Bundler . 解决方法是:

    • 在类似于 生产环境 环境的系统上生成Gemfile.lock,以获得与 生产环境 平台匹配的结果 . 实际上,这意味着如果您的 生产环境 系统是Windows,则只能在Windows上生成Gemfile.lock文件 .

    • 根本不提交Gemfile.lock文件,并在部署时确定 生产环境 机器上的依赖关系( bundle install ,不带 --deploy ) . 虽然一般不推荐,但在修复错误之前,这是一种经常使用的解决方法 . 例如,这是Heroku提供的推荐解决方案 .

    • 切换到JRuby,它将在Windows和Linux上具有相同的平台字符串( java ) . 我不认真对待这个,但我相信它会解决这个问题 .

    • 修复Bundler源代码中的问题,即帮助Bundler团队修复bug . :)

  • 2

    我认为问题是mysql gem没有正确发现所需的头文件 . 您可以通过转移到使用mysql2 gem来解决此问题,您只需在 database.yml 中更新数据库适配器以进行ActiveRecord集成 .

    此外,如果绝对必要,您可以将构建标志传递给C扩展gems:

    bundle config build.mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config .

  • 2

    你尝试过使用 rvmlink here)吗?它可以安装独立的Ruby虚拟机和Gemsets,因此您可以使用更像 生产环境 环境的环境 . 老实说,我不值得一试 .

    无论如何,我知道这不是你想听到的答案,但恕我直言Windows并不是在Rails中开发时最好的平台使用 . 我最近购买MacBook主要是为了开发Rails应用程序,它可以让您免于很多麻烦 . 您也可以在开发计算机上安装Linux并使用它,这比使用Windows端口或Cygwin更好 .

  • 1

    我们Engine Yard的工程师已经向Bundler提交了一个补丁来解决这个问题,如果在不同的平台上解冻宝石 . 在运行RailsInstaller演示教程之后,许多Windows尝试部署时遇到了同样的问题 . 我们发现的最佳解决方案是执行以下操作:

    • bundle install 与开发机器上的正常情况一样

    • 浏览 Gemfile.lock ,如果有任何行 -x86-mingw32 ,请删除该部分 .

    • bcrypt-ruby (3.0.1-x86-mingw32) 成为 bcrypt-ruby (3.0.1)

    • Gemfile.lock 的'Platforms'部分下添加 ruby

    • 确保使用platform标志在 Gemfile 中明确指定所需的gem . (不确定是否需要,但不会受到伤害)

    • Gemfile :`gem 'bcrypt-ruby','~> 3.0',:platform => 'ruby'

    • bundle install 再次保留 bcrypt-ruby (3.0.1) 行并再次添加 bcrypt-ruby (3.0.1-x86-mingw32) .

    如果您对Bundler补丁感到好奇,可以在https://github.com/carlhuda/bundler/pull/1451收到通知

    希望这有助于任何仍在寻找答案的人 .

  • 1

    我之前遇到过这个问题,使用mysql2 gem确实解决了这个问题 . 我知道's not the answer you'正在寻找,但将其与Diego 's answer and you'重新结合起来 .

  • 0

    你可以这样做:

    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
    

    顺便说一句,你应该将你的Gemfile.lock放入版本控制中,因为这样所有机器都将使用相同的gems版本运行应用程序 .

Related