У меня есть классический «монолитный» сервер, на котором запущено несколько Ruby-приложений под Passenger. Согласно документации для пассажира, это должно работать нормально, но я обнаружил несколько проблем, с которыми мне нужна помощь.
В документации указано:
Passenger may be installed with any Ruby interpreter. Once installed, you can run Passenger's Ruby parts under any Ruby interpreter you want, even if that Ruby interpreter was not the one you originally installed Passenger with.
[---]
Passenger is also capable of running Ruby web applications under any Ruby interpreter you want. So it is not important which Ruby you use to install Passenger: it will work regardless. Please refer to the documentation for the passenger_ruby directive to learn how run different web applications under different Ruby interpreters.
Я установил Passenger и модуль Apache, используя официальный пакет для моего дистрибутива SLES. Это довольно старая версия (5.0.18), но, поскольку дистрибутив все еще поддерживается, в него внесены исправления для исправления любых известных уязвимостей безопасности. Этот пассажир, конечно же, установлен в системе Ruby.
У меня также установлено несколько других Rubies. Если я укажу на новую установку с помощью директивы PassengerRuby, она сообщит, что пассажир не найден. Я понял, что Мне нужно установить Passenger под каждый интерпретатор Ruby позволяет запускать приложение. (Я не видел объяснения этого в документации.) Однако это создает проблему. При установке Passenger под новый Ruby я использую напрямую rubygems, а не RPM. Я могу попробовать выбрать ту же версию, что и RPM (5.0.18), но тогда это будет версия без исправлений. Я также могу просто позволить команде gem выбрать самую последнюю (наиболее исправленную) версию, но тогда приложение не запустится:
App 21959 stderr: /opt/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/passenger-5.3.0/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb:941:in `try_write_file': undefined method `try_write_file' for #<Hash:0x0000560031e58c88> (NoMethodError)
App 21959 stderr: from /opt/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/passenger-5.3.0/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb:522:in `dump_envvars'
App 21959 stderr: from /opt/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/passenger-5.3.0/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb:464:in `dump_all_information'
App 21959 stderr: from /opt/rubies/ruby-2.5.1/lib/ruby/gems/2.5.0/gems/passenger-5.3.0/src/ruby_supportlib/phusion_passenger/loader_shared_helpers.rb:394:in `about_to_abort'
App 21959 stderr: from /usr/lib64/passenger/5.0.18//helper-scripts/rack-preloader.rb:89:in `rescue in init_passenger'
App 21959 stderr: from /usr/lib64/passenger/5.0.18//helper-scripts/rack-preloader.rb:72:in `init_passenger'
App 21959 stderr: from /usr/lib64/passenger/5.0.18//helper-scripts/rack-preloader.rb:152:in `<module:App>'
App 21959 stderr: from /usr/lib64/passenger/5.0.18//helper-scripts/rack-preloader.rb:29:in `<module:PhusionPassenger>'
App 21959 stderr: from /usr/lib64/passenger/5.0.18//helper-scripts/rack-preloader.rb:28:in `<main>'
Похоже, что вспомогательный скрипт из «основного» пассажира подключается к новому пассажиру. И я предполагаю, что ошибка в том, что сом API мог измениться?
Итак, это моя первая проблема - требует ли установленный Passenger, чтобы каждый используемый интерпретатор Ruby имел собственную установку одной и той же версии Passenger? Как ты с этим справишься?
Теперь предположим, что я решил первый шаг и установил совместимые пассажиры. Затем снова пытаюсь запустить приложение:
App 1407 stdout:
[ 2018-05-15 21:34:57.4890 1367/7f1eda77b700 App/Implementation.cpp:303 ]: Could not spawn process for application /myApp: An error occured while starting up the preloader.
Error ID: 5a8f172f
Error details saved to: /var/run/passenger/passenger-error-XwWBnN.html
Message from application: You have already activated rack 2.0.5, but your Gemfile requires rack 2.0.3. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
Оказывается, сам Passenger зависит от Rack. Гем втянул последнюю версию - Rack 2.0.5. Passenger загружает эту версию, а затем выполняет настройку Bundler. Но приложение заблокировано до версии 2.0.3. Добавление пакета exec к директиве PassengerRuby не решает эту проблему, поскольку тогда сам Passenger не будет доступен - если я не добавлю его в Gemfile, в котором документация довольно четко заявляет не должна быть необходимой.
Таким образом, я могу синхронизировать эти версии, но тогда мне нужно будет синхронизировать версию Rack в приложениях все под определенным интерпретатором Ruby. Это значительно снижает пользу сборщика, он был предназначен для решения такого рода проблем. Или мне нужно связать свои приложения с текущим методом развертывания. Каков наилучший (наименее плохой) способ решить эту проблему?

Вы можете использовать RVM? Это должно помочь вам управлять несколькими рубинами и драгоценными камнями.
В своей системе я заметил, что достаточно одного модуля Passenger, как и написано в документации. Я установил его с gem install passenger в пустой гемсет.
Я заметил одну непонятную вещь: директива PassengerRuby (в случае Apache) для каждого VirtualHost должна указывать на гемсет каждого приложения, нет - на гемсет, на котором установлен модуль Passenger, или на какой-либо общий (анонимный) гемсет. В противном случае вы получите сбивающее с толку множество пересекающихся гемсетов. Рубиновая версия, упомянутая в PassengerRuby, не обязательно должна быть той же, с которой был скомпилирован Passenger. Пример из моей установки CentOS:
PassengerRuby /usr/local/rvm/gems/ruby-2.4.2@gemset-of-my-app/wrappers/ruby