Why does PDFKit/wkhtmltopdf hang but renders PDF as expected when Rails app is killed?

20,518

Solution 1

The problem is with wkhtmltopdf itself, specifically, any version after 0.9.9. wkhtmltopdf hangs when run directly from the command-line.

Steps to correct:

brew uninstall wkhtmltopdf
cd /usr/local/Library/Formula/
git checkout 6e2d550 /usr/local/Library/Formula/wkhtmltopdf.rb
brew install wkhtmltopdf

Then verify the correct version is installed wkhtmltopdf --version which should yield wkhtmltopdf 0.9.9

Citations:

  1. https://github.com/mileszs/wicked_pdf/issues/110
  2. http://wearepandr.com/blog/article/homebrew-and-installing-old-package-versions#blog_nav

Solution 2

Try the last version. The easy way install on MacOS:

brew install Caskroom/cask/wkhtmltopdf

Solution 3

The fix by scarver2 worked for me as advertised. But I needed a more recent version of wkhtmltopdf. Since the homebrew version still seems outdated (it still hangs on the command line), and since there isn't a recent precompiled binary available, I used the os x build script to compile one myself:

$ git clone [email protected]:wkhtmltopdf/wkhtmltopdf.git
$ cd wkhtmltopdf
$ ./build_osx.sh     # i'm running 10.9.2
$ bin/wkhtmltopdf --version                                                                                  
Name:
  wkhtmltopdf 0.12.1-72a9f2066fe9ffd162dec007a4d9b6a5cd63b670
$ curl www.example.com | bin/wkhtmltopdf - test.pdf  # render pdf of example.com
$ open test.pdf   # to confirm pdf 

I'm using pdfkit 0.6.2 with Rails 3.2.17. I put the binary in /vendor and, in a pdfkit initializer, pointed to it with config.wkhtmltopdf. So far, so good.

Solution 4

I got the same issue. It works when I added: 'config.threadsafe!' in application.rb as the answer in the stack. Hope this help.

Share:
20,518
robmclarty
Author by

robmclarty

Homepage Github Twitter CV

Updated on August 04, 2020

Comments

  • robmclarty
    robmclarty almost 4 years

    Background

    After reading around it seemed to me that Prawn is out and wkhtmltopdf is in. It also seems like the PDFKit and wicked_pdf gems for Rails are the new cool. So I found a screencast by Ryan on how to use PDFKit. I installed everything, tested wkhtmltopdf on the CLI with no problems, fiddled around with Rails settingsto run multiple processes so the asset pipeline works, and all seemed good, except I'm still stuck at the very end of the process (actually getting the PDF response from the server).

    Question

    When I request a .pdf version of my view (I'm using the PDFKit Middleware option) my browser just sits there waiting for a response, but as soon as I kill the Rails process the PDF I expected to get only then pops up in my browser window. What gives?

    What I'm Using

    • OS: OSX 10.8.1
    • Rails: 3.2.8
    • Ruby: 1.9.3
    • wkhtmltopdf: 0.11.0_rc1 (although when I run wkhtmltopdf -V it says 0.10.0_rc2)
    • qt: 4.8.2

    What I've Done

    • used the PDFKit middleware by loading config.middleware.use "PDFKit::Middleware" in my application.rb file.
    • included gem 'pdfkit' in my Gemfile and installed it with Bundler
    • set the .pdf mime-type in my mime_types.rb initializer with Mime::Type.register_alias "application/pdf", :pdf
    • added config.threadsafe! to config/environments/development.rb for multiple threads so asset pipeline doesn't conflict with PDF engine
    • tested wkhtmltopdf http://www.google.com google.pdf and it generated a PDF of the Google homepage as expected
    • tried swapping PDFKit for wicked_pdf and encountered the same problem (hanging, but when Rails process is killed the PDF renders as expected)

    What it Looks Like

    This is the regular html page rendered by Rails (I've blurred the client details): enter image description here

    This is the CLI output by Rails when I try to navigate to localhost:3000/some/path.pdf. (the app hangs while waiting for a response): enter image description here

    When I finally kill the Rails process with ctrl-c the PDF finally shows up in the browser as I expected to see it (CSS and HTML rendered properly, so assets seem to load fine): enter image description here

    Conclusions So Far

    Swapping PDFKit for wicked_pdf and getting the same results seems to make me think the problem isn't with those libraries, but something to do with my development environment. But wkhtmltopdf runs fine off the command line, so that makes me think that it and QT are doing their job. The problem must be in Rails. Maybe I'm not configuring something properly?

    Plea for Help

    How do I determine what exactly the problem is and how do I fix it?

    I'll love you if you can help me <3

    Update

    I've also tried using an alternative method of rendering the PDF (with .to_pdf) without the middleware option as follows (doing this I commented out config.middleware.use "PDFKit::Middleware" from my application.rb file):

    respond_to do |format|
        format.html
        format.pdf do
            html = '<html><body>This is a test.</body></html>'
            @pdf = PDFKit.new(html)
    
            send_data @pdf.to_pdf, 
                :filename => 'whatever.pdf', 
                :type => 'application/pdf', 
                :disposition => 'attachment'
        end
    end
    
  • robmclarty
    robmclarty over 11 years
    Yes, I've implemented config.threadsafe! in my development.rb file. I understand there can be a deadlock between wkhtmltopdf and the asset pipeline when using default webrick because it uses only one thread. My app was previously doing nothing before I did this, so this did indeed help get things a step further. However, it's still hanging while waiting for the PDF file (i guess the browser isn't receiving it from the server?)
  • mfilej
    mfilej about 11 years
    Steps 2-4 in a single command: brew install https://raw.github.com/mxcl/homebrew/6e2d550cf4961129a790bfb‌​0973f8e88704f439d/Li‌​brary/Formula/wkhtml‌​topdf.rb
  • scarver2
    scarver2 about 11 years
    If you have Ruby installed, you can bypass all of this Homebrew manipulation and just gem install wkhtmltopdf. Delete the existing Homebrew symlink: rm /usr/local/bin/wkhtmltopdf. Then link to the gem's binary e.g. ln -s ~/.rvm/gems/ruby-2.0.0-p0/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf. Use which wkhtmltopdf command to find the binary. Add gem 'wkhtmltopdf' to the GemFile. If using the wicked_pdf gem, set its configuration to WickedPdf.config={exe_path: '/usr/local/bin/wkhtmltopdf'}. References: wkhtmltopdf gem (0.1.2) installs wkhtmltopdf binary version 0.8.3 patched qt.
  • genkilabs
    genkilabs over 10 years
    The gemfile gem 'wkhtmltopdf-binary' currently installs 0.9.9 for those interested in using a gem instead of brew
  • Clifton Labrum
    Clifton Labrum about 10 years
    I was attempting to use 0.11.x and after pulling all my hair out (including chest hair) I found this answer and wept like a child. You, my friend, have saved me.
  • januszm
    januszm over 8 years
    Even 0.9.9.3 is bad? I have these issues just after upgrading an app from Rails 3 to Rails 4 and Ruby from 1.9.3 to 2.2.1. I tried several versions of wkhtmltopdf ranging from 0.9.9 to 0.12.2.1 and generating PDF hangs for every version. I think that this must be related to Ruby version or PDFkit gem itself.
  • scarver2
    scarver2 over 8 years
    @januszm Many people are reporting success with the wkhtmltopdf-binary gem. If you need to run the latest version of wkhtmltopdf, try this fork of the gem github.com/dmitryrck/wkhtmltopdf_binary_gem
  • januszm
    januszm over 8 years
    In my case it fails on images on Rails 4. After I removed all image tags from the html template (converted to pdf) it works (but no images). It worked well on Rails 3.2 so this is clearly related to the Rails upgrade. It's explained here: stackoverflow.com/questions/20377401/…
  • Marklar
    Marklar over 8 years
    @scarver2 referring to your comment on Sep 26, 2015, does that mean the latest version of wkhtmltopdf no longer has the problem? Would we need to use the fork of the gem you recommended or could we just install the latest version with brew?
  • scarver2
    scarver2 over 8 years
    @Marklar The wkhtmltopdf_binary gem actually bypasses any Homebrew installation and uses the version found within gem's bin folder. The author, Dmitry Rocha, has been keeping the binaries current.
  • Marklar
    Marklar over 8 years
    @scarver2 thanks for taking the time to answer. Are you sure the binaries are current in the gem even though the gem hasn't been updated in 4 years?
  • scarver2
    scarver2 over 8 years
    @Marklar Use this branch github.com/dmitryrck/wkhtmltopdf_binary_gem It was updated last month.
  • michael
    michael over 8 years
    if you are getting Please switch this formula to SHA256. when installing the old version try brew install https://gist.githubusercontent.com/semanticart/389944e2bcdba‌​5424e01/raw/9ed12047‌​7b57daf10d7de6d585d4‌​9b2017cd6955/wkhtmlt‌​opdf.rb. See: gist.github.com/semanticart/389944e2bcdba5424e01
  • mikebridge
    mikebridge over 8 years
    It didn't work for me either until I switched from thin back to webrick.
  • claudevandort
    claudevandort almost 7 years
    Wena abel, gracias! xD!
  • Serenthia
    Serenthia over 4 years
    Note that this now needs to be brew cask uninstall wkhtmltopdf and brew cask install wkhtmltopdf.