Как запустить "bundle exec" из определенной версии Ruby, используя RVM, когда среды оболочки нет
Хорошо, я должен сделать признание - я все еще запускаю обширную настройку FCGI (только много настроенных серверов). Я пытаюсь адаптировать его к рвм. В настройках fcgi я могу указать команду командной строки для запуска моего приложения (Sinatra, Rack, Bundler, все это), и это то, что я бы сделал без rvm
"bin-path" => "bundle exec rackup",
"bin-environment" => (
"RACK_ENV" => "development"
),
при условии, что мой файл рэкапа просто config.ru. Теперь на моем Mac это работает:
"bin-path" => env.HOME + "/.rvm/gems/ruby-1.9.2-p180/bin/bundle exec rackup " + CWD + "/config.ru",
"bin-environment" => (
"BUNDLE_GEMFILE" => CWD + "/Gemfile",
"RACK_ENV" => "development"
),
но не на сервере. Когда диспетчеры запускаются, они получают урезанное окружение, в котором обман оболочки RVM больше не работает. Думаю, мне следует использовать опцию wrapper, чтобы создать какую-то обертку, но я не совсем понимаю, как это облегчит мою проблему и какие аргументы использовать. У кого-нибудь есть опыт применения конкретных исполняемых файлов ruby и gem без загрузки оболочки env RVM?
PS Для предотвращения не по теме ответов, спасибо, мне не нужны Ruby 1.8.7, Passenger или nginx.
4 ответа
Вы должны быть в состоянии использовать rvm exec
:
Как и большинство операций с наборами rvm, exec позволяет выполнять команды выполнения для всех установленных рубинов. В отличие от других, есть ключевое различие - exec позволяет вам запускать любую команду (вместо просто ruby / gem и т. П.), И если она запускается только с одним рубином, она выполняет эквивалент exec (например, без сообщения об ошибке) после настройка среды.
Если rvm
исполняемый файл находится на $PATH
для пользователя вашего веб-сервера вы можете сделать:
"bin-path" => "rvm 1.9.2-p180 exec bundle exec rackup"
РЕДАКТИРОВАТЬ: Оказывается, Джейкоб был прав, извините за понижение. Я решил немного расширить это решение.
Теперь я могу использовать двоичный файл rvm, но, поскольку он установлен пользователем, его нет в $PATH на моем ноутбуке.
bigbuk:~ julik$ which rvm
bigbuk:~ julik$
но это на сервере.
[julik@serveur ~]$ which rvm
/usr/local/rvm/bin/rvm
[julik@serveur ~]$
Это то, что смутило меня. Только он должен вызываться с абсолютным путем (поскольку FCGI работает без установки правильного PATH). Таким образом, двоичный путь должен быть настроен соответствующим образом, и, конечно же, rvm также правильно установит для нас GEM_HOME и GEM_PATH. Единственное, что действительно нужно установить, это BUNDLE_GEMFILE, поскольку Bundler не может автоматически определить его из файла Rackup, а cwd процесса FCGI является мусором.
"bin-path" => "/usr/local/rvm/bin/rvm 1.9.2-p180 exec bundle exec rackup /home/user/websites/behandelaar-web/current/web-root/",
"bin-environment" => (
"BUNDLE_GEMFILE" => "/home/user/websites/behandelaar-web/current/Gemfile",
"RACK_ENV" => "production",
),
Тем не менее, наличие специального сценария-обертки, написанного на Ruby, имеет некоторые преимущества, поскольку и rackup, и bundle очень плохо работают с пузырьковыми исключениями, и, если, скажем, есть проблемы с самим гемом FCGI (что было у меня - у него было 1.8-специфично). обработка строковых байтов) эти исключения не будут правильно пузыриться через этот многоуровневый стек оберток, и наиболее проницательной вещью, которую вы увидите в отношении отчетов об ошибках, будет страница состояния 500 с вашего веб-сервера.
Вы пытались настроить системные переменные следующим образом:
/etc/environment
BUNDLE_GEMFILE=path_to_the_file
RACK_ENV=production
RUBY_VERSION='ruby-1.9.2-p180'
GEM_PATH='$HOME/rvm/...'
Вы можете настроить любые переменные rubygems (окружение gem) и rvm на уровне системы, а не только для конкретного пользователя.
Ок, rvm-shell кажется решением проблемы, так как это исполняемый файл, а не функция оболочки. Важная вещь, так что укажите сами GEM_HOME и GEM_PATH!
"bin-path" => "/usr/local/rvm/gems/ruby-1.9.2-p180/bin/bundle2 /home/user/websites/behandelaar-web/current/web-root/config.ru",
"bin-environment" => (
"BUNDLE_GEMFILE" => "/home/user/websites/behandelaar-web/current/Gemfile",
"RACK_ENV" => "production",
"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",
), ),
Сценарий "bundle2" представляет собой смесь между bundle exec и rackup, с дополнительным бонусом приличных отчетов об ошибках (так как fcgi не имеет STDERR и не STDOUT, а множество элементов в цепочке поглощают все возможные исключения, приводящие к сбоям).
#!/usr/local/rvm/rubies/ruby-1.9.2-p180/bin/ruby
#
# Generated Manually!
begin
require 'rubygems'
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end
gem 'bundler', version
load Gem.bin_path('bundler', 'bundle', version)
load Gem.bin_path('rack', 'rackup', version)
rescue Exception => e
File.open("/tmp/fcgrun-crash.log", "w") do | f |
f.puts(ENV.inspect)
f.puts(e.class.to_s)
f.puts(e.message)
f.puts(e.backtrace.join("\n"))
end
# and raise further
raise e
end