5

I've looked high and low on stackoverflow searching for other solutions and none of them seem to have a suitable answer. So I'll try to be as specific as possible.

We are using wicked_pdf (0.9.7) and wkhtmltopdf-binary (0.9.9.1) in a Ruby on Rails application on Ruby 2.0 and Rails 4

Our code runs locally when we clone the repository and startup the server, but when we push to production (4 nodes), it occasionally works.

This is the error we are getting:

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' 

Here is the relevant code within the application:

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 
  • We've run (successfully) the wkhtmltopdf using bundle exec directly on the server, but when we hit the page, it will error out 500 about 3/4 of the time.
  • We've also run it in rails console with success.
  • We have used the basic wkhtmltopdf to generate a pdf from a webpage.
  • We are currently working on generating a pdf from a local file where wicked_pdf would write a temp file and trying to generate the file from there.

Any input would be gratefully appreciated.

12
  • It looks like it can't find the ruby executable itself. I can't imagine why that would only happen occasionally. (You don't happen to have four machines behind a load balancer, for example? Edit: wait no that's an error message from ruby. Commented Oct 31, 2013 at 21:46
  • Hold on, I just re-read your question--you do! It sounds like one of the machines doesn't have the pdf converter installed properly. Commented Oct 31, 2013 at 21:47
  • What you could do is 1) try to discover if the same node fails every time and 2) try to discover what the command looks like when it does work by logging it out. That should point to a solution. Commented Oct 31, 2013 at 21:52
  • Yes, but the pdf converter is installed with bundler. We've run the wicked_pdf generation code that uses wkhtmltopdf on at least 3 of the 4 nodes, all with success. That's why it's so confusing. And yes, we've been troubleshooting this all day with the logs. We can't seem to figure it out. We're running out of places to look. :( Commented Oct 31, 2013 at 21:54
  • Do you have the option of switching off one node at a time until the problem disappears, then overwriting the bad node with a clone of one of the good ones? Commented Oct 31, 2013 at 22:28

2 Answers 2

4

The issue was that wkhtmltopdf was executing a shell script to determine the version of the binary to use which failed because apache has no shell (and for good reason). The solution was to set the binary explicitly.

Since our dev, staging, and prod environments vary, we created a RBConfig script that is executed within the rails app (no shell access necessary):

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}" } 

There are several other ways to do this. For example, developing locally, your user should have shell access, in which case you really only need to set the binary explicitly for your production environment:

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

Or, as we have done, set up our chef configuration to set up all of our environments with the proper binaries. It also let us make sure all the fonts that we need were installed for production.

Sign up to request clarification or add additional context in comments.

Comments

0

For anyone else running across this where the selected answer does not work.

I ran into this problem running Passenger on Nginx. The user that Nginx and Passenger were running as had ruby in its PATH which caused some confusion.

The issue turned out to be that the /etc/init.d/nginx file specifies the PATH that nginx will have while running, which turned out not to include ruby.

Adding ruby to the PATH variable in /etc/init.d/nginx fixed the issue.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.