运行时错误(无法执行)无法使用wkhtmltopdf-binary生成wicked_pdf

时间:2013-10-31 21:15:12

标签: ruby-on-rails ruby pdf wkhtmltopdf wicked-pdf

我在stackoverflow上寻找其他解决方案时看起来很高和很低,但它们似乎都没有合适的答案。所以我会尝试尽可能具体。

我们在Ruby 2.0和Rails 4上的Ruby on Rails应用程序中使用wicked_pdf(0.9.7)和wkhtmltopdf-binary(0.9.9.1)

当我们克隆存储库并启动服务器时,我们的代码在本地运行,但是当我们推送到生产(4个节点)时,偶尔会工作。

这是我们得到的错误:

INFO: ***************WICKED***************
Rendered application/index.pdf.haml within layouts/pdf (209.2ms)
Rendered application/_header.pdf.haml within layouts/pdf (1.5ms)
Completed 500 Internal Server Error in 3406ms
FATAL: RuntimeError(Failed to execute:\n"/opt/application/releases/5405db831e02eb2987cc06b243333776ce9c34b8ab6db3e58e93f39c3f933621/vendor/bundle/ruby/2.0.0/bin/wkhtmltopdf" -q  --header-html "file:////tmp/wicked_header_pdf20131031-15836-12qkok6.html" --footer-right "[page] of [topage]" --footer-font-size 9    --margin-top 50  --encoding "UTF-8"   "file:////tmp/wicked_pdf20131031-15836-b874ab.html" "/tmp/wicked_pdf_generated_file20131031-15836-1ibji4k.pdf" \nError: PDF could not be generated!\n Command Error: /usr/bin/env: ruby: No such file or directory\n)
 vendor/bundle/ruby/2.0.0/gems/wicked_pdf-0.9.7/lib/wicked_pdf.rb:69:in `rescue in pdf_from_string'
 vendor/bundle/ruby/2.0.0/gems/wicked_pdf-0.9.7/lib/wicked_pdf.rb:73:in `pdf_from_string'
 vendor/bundle/ruby/2.0.0/gems/wicked_pdf-0.9.7/lib/pdf_helper.rb:63:in `make_pdf'
 vendor/bundle/ruby/2.0.0/gems/wicked_pdf-0.9.7/lib/pdf_helper.rb:76:in `make_and_send_pdf'
 vendor/bundle/ruby/2.0.0/gems/wicked_pdf-0.9.7/lib/pdf_helper.rb:21:in `render_with_wicked_pdf'

以下是申请表中的相关代码:

的Gemfile

gem 'wicked_pdf', '~> 0.9.7'
gem 'wkhtmltopdf-binary', '~> 0.9.9'

Gemfile.lock的

wicked_pdf (0.9.7)
  rails
wkhtmltopdf-binary (0.9.9.1)

controller.rb

def show
    render pdf: file_name,
          layout: 'pdf',
          margin: {
            top: 30
          },
          header: {
            html: {
              template: '_header.pdf.haml'
            }
          },
          footer: {
            right: I18n.t('pdf.page_description'),
            font_size: 9
          },
          encoding: 'UTF-8'
end
  • 我们直接在服务器上运行(成功)使用bundle exec的wkhtmltopdf,但是当我们点击页面时,它会在3/4的时间内出错500。
  • 我们也成功地在rails控制台中运行它。
  • 我们使用基本的wkhtmltopdf从网页生成pdf。
  • 我们正在努力从本地文件生成pdf,其中wicked_pdf会写一个临时文件并尝试从那里生成文件。

非常感谢任何意见。

2 个答案:

答案 0 :(得分:3)

问题是wkhtmltopdf正在执行一个shell脚本来确定要使用的二进制文件版本失败,因为apache没有shell(并且有充分的理由)。解决方案是明确设置二进制文件。

由于我们的dev,staging和prod环境各不相同,我们创建了一个在rails app中执行的RBConfig脚本(无需shell访问):

require 'rbconfig'

if RbConfig::CONFIG['host_os'] =~ /linux/
  arch = RbConfig::CONFIG['host_cpu'] == 'x86_64' ? 'wkhtmltopdf_linux_x64' : 'wkhtmltopdf_linux_386'
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
  arch = 'wkhtmltopdf_darwin_386'
else
  raise "Invalid platform. Must be running Intel-based Linux or OSX."
end

WickedPdf.config = {
  exe_path: "#{ENV['GEM_HOME']}/gems/wkhtmltopdf-binary-#{Gem.loaded_specs['wkhtmltopdf-binary'].version}/bin/#{arch}"
}

还有其他几种方法可以做到这一点。例如,在本地开发,您的用户应该具有shell访问权限,在这种情况下,您实际上只需要为生产环境明确设置二进制文件:

if Rails.env.production?
    WickedPdf.config = { ... }
end

或者,正如我们所做的那样,设置我们的主厨配置以使用适当的二进制文件设置所有环境。它还让我们确保我们需要的所有字体都已安装用于生产。

答案 1 :(得分:0)

对于在此处遇到选定答案不起作用的其他人。

我遇到了在Nginx上运行Passenger的问题。 Nginx和Passenger运行的用户在其PATH中运行了红宝石,这引起了一些混乱。

问题原来是/etc/init.d/nginx文件指定了nginx在运行时将拥有的PATH,结果证明不包含ruby。

将ruby添加到/etc/init.d/nginx中的PATH变量中解决了问题。