#ruby-on-rails #ruby #ubuntu #wicked-pdf
#ruby-on-rails #ruby #ubuntu #wicked-pdf
Вопрос:
Я столкнулся с проблемой на нашем производственном сервере, у нас есть приложение Rails, которое генерирует PDF-файл с использованием gem wicked_pdf
, и оно выдает следующую ошибку:
Failed to execute:
["/var/www/myapp/vendor/cache/ruby/2.6.0/bin/wkhtmltopdf", "file:////tmp/wicked_pdf20201004-5058-g9f64a.html", "/tmp/wicked_pdf_generated_file20201004-5058-1gjfrw5.pdf"]
Error: PDF could not be generated!
Command Error: /usr/bin/env: 'ruby2.6': No such file or directory
Теперь самое странное, что это отлично работает из задачи rake (задача rake выполняется с sudo
помощью)
и, конечно, ruby отлично справляется:
$ which ruby
/usr/bin/ruby
$ which ruby2.6
/usr/bin/ruby2.6
$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-gnu]
$ echo $PATH
/home/julien/bin:/home/julien/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
Приложение Rails запускается вместе с www-data
пользователем.
Ubuntu 16.04.5 LTS.
Я предполагаю, что в любом bash, который приложение использует для выполнения двоичного файла, что-то отсутствует в нем $PATH
, или, может быть, мне где-то нужна символическая ссылка, но я понятия не имею, есть идеи?
Как я могу отладить это, чтобы понять, в чем проблема? Как я могу проверить и, возможно, изменить, какой путь к оболочке загружается Rails?
Обновить
Приложение Rails запускается с помощью Nginx Passenger.
ENV['PATH']
выводит следующее:
/var/www/myapp/vendor/cache/ruby/2.6.0/bin
Вот соответствующая часть кода, которая генерирует PDF:
#generate the PDF
pdf = WickedPdf.new.pdf_from_string(
ActionController::Base.new.render_to_string(
template: 'templates/_doc',
locals: {
url: self.url,
signature: sig,
name: full_name,
title: "some title"
}
)
)
#save the file
save_path = Rails.root.join(PATH_TO_STORE_FILE, "some-filename-#{self.clean_url}.pdf")
File.open(save_path, 'wb') do |file|
file << pdf
end
Комментарии:
1. Это вероятная проблема с путем. Www-данные не совпадают с вашей собственной учетной записью пользователя, и поэтому путь не настроен одинаково. Под какой системой вы используете Rails? Пассажир Apache? Существует много способов задать ПУТЬ, чтобы обойти эту проблему, но трудно дать прямой ответ, не зная всех подробностей.
2. Я предлагаю вывести
ENV['PATH']
на одной из ваших страниц Rails для начальной отладки.3. Также как выглядит код, который вызывает
wkhtmltopdf
. Пожалуйста, включите этот код в сообщение.4. @Casper я добавил запрошенную информацию, я очень удивлен тем, как мало в ней есть
EN['PATH']
, неудивительно, что он не может найти ruby, как я могу это обновить?
Ответ №1:
Вместо того, чтобы выяснять, где редактировать PATH
, самый простой способ решить вашу проблему:
cd /var/www/myapp/vendor/cache/ruby/2.6.0/bin
ln -s /usr/bin/ruby2.6 .
Таким образом, у вас будет ссылка, указывающая ruby2.6
на папку вашего поставщика bin, и поскольку эта папка находится в пути к вашему веб-серверу, это должно устранить вашу проблему.
Ответ №2:
WickedPdf пытается выяснить, где wkhtmltopdf
находится, вызывая which wkhtmltopdf
в некоторых случаях. Здесь он собирает двоичную заглушку (binstub), которая вызывает Ruby 2.6, но процесс, вызывающий его, не имеет этого в своем ПУТИ.
Вы можете явно указать путь к вашему wkhtmltopdf
двоичному файлу следующим образом:
WickedPdf.config = {
exe_path: '/usr/local/bin/wkhtmltopdf'
}
В идеале это должен быть прямой путь к фактическому двоичному файлу, а не к binstub, однако некоторые драгоценные камни, которые предоставляются wkhtmltopdf
в виде двоичного файла, используют binstub для переключения двоичных файлов в зависимости от платформы, выполняющей его.
При использовании одного из них должно сработать что-то вроде этого:
WickedPdf.config = {
exe_path: "#{ENV['GEM_HOME']}/gems/wkhtmltopdf-binary-#{Gem.loaded_specs['wkhtmltopdf-binary'].version}/bin/wkhtmltopdf_linux_amd64"
}