Как запустить "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
Другие вопросы по тегам