Apache + RVM Ruby 1.9.2 + Passenger = no such file to load — bundler
Довольно популярная ошибка, которая имеет вагон всяких решений в интернете, но при этом ни одно из них до конца не работает. Типичной средой ее обитания является Ruby, установленный через RVM (установлена под рутом => для всех), на который установлен Ruby on Rails 3 и все это дело запущено под Apache’м через Passenger. Т.е. когда приложение уже вот-вот должно запуститься и апачевская TestPage уже не светит появляется она.
Разумеется ошибка возникает тогда, когда сам гем bundler прекрасно установлен и при запуске рельсов под webrick’ом все прекрасно работает:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ gem list | grep bundler bundler (1.0.15) $ rails s => Booting WEBrick => Rails 3.0.7 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2011-06-29 13:14:21] INFO WEBrick 1.3.1 [2011-06-29 13:14:21] INFO ruby 1.9.2 (2011-02-18) [x86_64-linux] [2011-06-29 13:14:21] INFO WEBrick::HTTPServer#start: pid=4240 port=3000 |
Многие статьи в интернете при первых симптомах оной рекомендуют верно настроить путь Ruby в конфигурации апача, например:
1 2 3 4 | PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p180/ gems/passenger-3.0.7 PassengerRuby /usr/local/rvm/rubies/ruby-1.9.2-p180/ bin/ruby |
Потому как они предполагают, что среда в которой запускается рельсы под апачем не подозревает о существовании bundler’а. И здесь есть рациональное зерно и даже возможно удастся подобрать такой путь к руби.
Как можно заметить ошибка возникает тут:
1 2 | /usr/local/rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/ rubygems/custom_require.rb |
Именно это скрипт ругается, а значит именно его мы и будем исправлять.
правильная среда
Прежде всего нужно найти ту правильную среду, а точнее те значения переменных окружения при которых все работает. Для этого надо с теми настройками RVM, под которыми корректно запускаются рельсы выполнить команду RVM info
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | $ rvm info ruby-1.9.2-p180: bla-bla-bla... rvm: bla-bla-bla... ruby: bla-bla-bla... homes: bla-bla-bla... binaries: ruby: "/usr/local/rvm/rubies/ruby-1.9.2-p180 /bin/ruby" irb: "/usr/local/rvm/rubies/ruby-1.9.2-p180 /bin/irb" gem: "/usr/local/rvm/rubies/ruby-1.9.2-p180 /bin/gem" rake: "/usr/local/rvm/gems/ruby-1.9.2-p180 /bin/rake" environment: PATH: "/usr/local/rvm/gems/ruby-1.9.2-p180 /bin:/usr/local/rvm/gems/ruby-1.9.2-p180@global/bin: /usr/local/rvm/rubies/ruby-1.9.2-p180/bin:/usr/local /rvm/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr /local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr /bin:/root/bin" GEM_HOME: "/usr/local/rvm/gems/ruby-1.9.2-p180" GEM_PATH: "/usr/local/rvm/gems/ruby-1.9.2-p180: /usr/local/rvm/gems/ruby-1.9.2-p180@global" MY_RUBY_HOME: "/usr/local/rvm/rubies/ruby-1.9.2-p180" IRBRC: "/usr/local/rvm/rubies/ruby-1.9.2-p180 /.irbrc" RUBYOPT: "" gemset: "" |
И она выдаст то что нужно:
- на 16-й строке верный путь до правильного интерпритатора Ruby, который нужно прописать в параметре Apache’а
PassengerRuby
- строки 26-37 – верная настройка среды под, которой все работает
ненавистный custom_require.rb
1 2 | /usr/local/rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/ rubygems/custom_require.rb |
Находим ту самую строку ошибки:
45 46 47 48 49 50 51 52 | def require path if Gem.unresolved_deps.empty? or Gem.loaded_path? path then gem_original_require path else spec = Gem.searcher.find_active path ... |
И тут, чтобы убедиться что ENV там кривое либо отсутствует напрочь, можно например запилить дверь вывод ENV в файл:
45 46 47 48 49 50 51 52 53 | def require path if Gem.unresolved_deps.empty? or Gem.loaded_path? path then File.new('/tmp/envs','a') { |f| f.puts path} gem_original_require path else spec = Gem.searcher.find_active path ... |
Однако, нам нужно не это, а наладить запуск рельсов, поэтому вместо приколов просто прописываем в начало метода def require path
правильные настройки переменных окружения, которые мы нашли при rvm info
:
45 46 47 48 49 50 51 52 53 54 55 | def require path ENV['PATH']="/usr/local/..." ENV['GEM_HOME']="/usr/local/..." ENV['GEM_PATH']="/usr/local/..." ENV['MY_RUBY_HOME']="/usr/..." ENV['IRBRC']="/usr/local/rvm/..." if Gem.unresolved_deps.empty? or Gem.loaded_path? path then ... |
Вот и все, после этих манипуляции мои рельсы завелись.
Помогло!
Благодарю сердечно.
да не за что. всегда рад помочь
У меня такая же проблема, только ruby 1.9.3 и в custom_require.rb такие строки:
require ‘rubygems’
module Kernel
alias gem_original_require require
def require(path) # :doc:
gem_original_require path
rescue LoadError => load_error
if load_error.message =~ /#{Regexp.escape path}\z/ and
spec = Gem.searcher.find(path) then
Gem.activate(spec.name, “= #{spec.version}”)
gem_original_require path
else
raise load_error
end
end
private :require
private :gem_original_require
end
Подскажите, куда тут пути прописать из вывода RVM info? Не шарю в этом…
я понятия не имею как это будет работать с 1.9.3, в ENV ли проблема, поможет ли мое решение для 1.9.2 итд, но вставлять нужно точно туда же как и при 1.9.2 т.е. непосредственно после
def require(path) # :doc: