CentOS环境下Rails 3.1.3应用启动报Bundler::GemNotFound错误
根因定位
- 运行环境错配是核心触发点:从完整报错栈的路径可以确认,当前Apache集成的Phusion Passenger模块,始终调用
ruby-1.9.2-p290@globalgem环境下的Bundler 1.3.5加载应用依赖,根本没有切到你之前准备好的Ruby 1.9.3环境。 - 依赖误清除是直接原因:数小时前应用运行正常,就是因为你在环境切换操作过程中,误将旧1.9.2环境下原本安装的activesupport-3.1.3从gem目录清除。你修改Gemfile后执行
bundle show activesupport能正常输出版本路径,是因为你操作时的交互shell已经切到Ruby 1.9.3环境,对应的3.1.4版本activesupport全部安装在1.9.3的gem目录下,和旧运行环境完全不互通。 - 锁文件不匹配:你当前目录下的Gemfile.lock还是锁定Rails 3.1.3的旧版本内容,就算你后续把Gemfile改回了3.1.3的配置,旧环境下对应的gem文件已经缺失,无法完成加载。
分步修复操作
路径1:快速回退到之前稳定的Ruby 1.9.2 + Rails 3.1.3运行状态
这是最短的恢复路径:
- 先切到实际运行的旧环境:执行
rvm use ruby-1.9.2-p290@global,匹配报错栈里显示的Passenger调用的Ruby环境 - 按照当前目录下的Gemfile.lock锁定的版本,执行
bundle install把缺失的activesupport-3.1.3及其他关联依赖装回当前环境 - 安装完成后执行
bundle check,确认所有依赖都能被正常识别 - 重启Apache服务,让Passenger重新加载应用
路径2:完整切换到Ruby 1.9.3 + Rails 3.1.4的目标环境
如果你确实要完成之前计划的版本升级:
- 先修改Gemfile中对应的rails、activesupport版本为3.1.4
- 删除旧的
Gemfile.lock文件,在Ruby 1.9.3对应的目标gemset下执行bundle install,重新生成依赖锁定文件 - 修改Apache配置文件中的
PassengerRuby指令,把原有的1.9.2 Ruby路径替换为Ruby 1.9.3对应的wrapper路径(一般格式为/usr/local/rvm/wrappers/ruby-1.9.3-pXXX@你使用的gemset/ruby) - 重启Apache服务,确认Passenger调用的Ruby版本和你安装gem的环境完全一致
注意事项
- Passenger是由Apache主进程启动的服务进程,不会继承你当前交互shell的RVM环境变量,永远读取Apache配置文件中写死的Ruby路径,不要默认认为你shell里装的gem,应用启动时就能找到。
- 调整依赖环境时,不要在未对齐运行环境的情况下执行
bundle clean,很容易误删旧环境下未被当前Gemfile引用的历史gem,触发这类找不到对应gem版本的报错。
内容的提问来源于stack exchange,提问作者Harry Tasker
相关产品推荐
相关产品推荐

