Search code examples
ruby-on-railsrubyherokuzbar

How can I get zbar to deploy on Heroku?


I am using the ruby-zbar gem in a rails app to scan barcodes from jpgs. I installed the zbar library using homebrew on my local machine and everything works fine. However, when deploying to Heroku I consistently get errors such as the following:

remote:        LoadError: Didn't find libzbar on your system
remote:        Please install zbar (http://zbar.sourceforge.net/) or set ZBAR_LIB if it's in a weird place
remote:        FFI::Library::ffi_lib() failed with error: library names list must not be empty

I've tried following the advice from this Stack Overflow post (Heroku Zbar Didn't find libzbar on your system (LoadError)), namely to set the ZBAR_LIB ENV variable to /app/vendor/lib/libzbar.so, or failing that to run heroku bash and try to find a file named libzbar.so and point ZBAR_LIB to its path.

However, I can't seem to find the heroku buildpack referenced in the original Stack Overflow post (the link to https://github.com/ballantyne/heroku-buildpack-zbar goes to a 404 page), so I can't replicate the solution outlined there.

I have tried all of the following buildpacks:

https://github.com/generalui/heroku-buildpack-zbar
https://github.com/robert-wallis/heroku-buildpack-zbar
https://github.com/robert-wallis/heroku-buildpack-zbar/tree/patch-1

During the build process I can see hopeful messages like this:

remote: -----> Multipack app detected
remote: -----> Fetching custom git buildpack... done
remote: -----> ZBAR app detected
remote: -----> Downloading and installing ZBAR
remote: -----> Configuring ZBAR
remote: -----> Make!
remote: -----> Make install !!!
remote: -----> Writing profile script
remote: -----> Fetching custom git buildpack... done
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.2.1

But setting ZBAR_LIB to /app/vendor/lib/libzbar.so gives me some version of this error:

remote:        LoadError: Didn't find libzbar on your system
remote:        Please install zbar (http://zbar.sourceforge.net/) or set ZBAR_LIB if it's in a weird place
remote:        FFI::Library::ffi_lib() failed with error: Could not open library '/app/vendor/lib/libzbar.so': /app/vendor/lib/libzbar.so: cannot open shared object file: No such file or directory

And trying to find libzbar.so on heroku run bash has not been successful for me -- I can see many files that are similar in name (even a libzbar.rc) but none that fits the bill.

~ $ find / -name '*libzbar*'
find: `/var/lib/polkit-1': Permission denied
/app/vendor/zbar/plugin/.deps/plugin_libzbarplugin_la-plugin.Plo
/app/vendor/zbar/qt/.deps/qt_libzbarqt_la-QZBar.Plo
/app/vendor/zbar/qt/.deps/qt_libzbarqt_la-QZBarThread.Plo
/app/vendor/zbar/qt/.deps/qt_libzbarqt_la-moc_QZBarThread.Plo
/app/vendor/zbar/qt/.deps/qt_libzbarqt_la-moc_QZBar.Plo
/app/vendor/zbar/gtk/.deps/gtk_libzbargtk_la-zbargtk.Plo
/app/vendor/zbar/gtk/.deps/gtk_libzbargtk_la-zbarmarshal.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-symbol.lo
/app/vendor/zbar/zbar/zbar_libzbar_la-video.o
/app/vendor/zbar/zbar/zbar_libzbar_la-error.lo
/app/vendor/zbar/zbar/processor/zbar_libzbar_la-lock.lo
/app/vendor/zbar/zbar/processor/.libs/zbar_libzbar_la-lock.o
/app/vendor/zbar/zbar/processor/zbar_libzbar_la-lock.o
/app/vendor/zbar/zbar/processor/.deps/zbar_libzbar_la-null.Plo
/app/vendor/zbar/zbar/processor/.deps/zbar_libzbar_la-x.Plo
/app/vendor/zbar/zbar/processor/.deps/zbar_libzbar_la-posix.Plo
/app/vendor/zbar/zbar/processor/.deps/zbar_libzbar_la-lock.Plo
/app/vendor/zbar/zbar/processor/.deps/zbar_libzbar_la-win.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-config.o
/app/vendor/zbar/zbar/zbar_libzbar_la-processor.o
/app/vendor/zbar/zbar/zbar_libzbar_la-refcnt.lo
/app/vendor/zbar/zbar/zbar_libzbar_la-convert.o
/app/vendor/zbar/zbar/zbar_libzbar_la-video.lo
/app/vendor/zbar/zbar/zbar_libzbar_la-window.o
/app/vendor/zbar/zbar/video/.deps/zbar_libzbar_la-null.Plo
/app/vendor/zbar/zbar/video/.deps/zbar_libzbar_la-v4l1.Plo
/app/vendor/zbar/zbar/video/.deps/zbar_libzbar_la-v4l2.Plo
/app/vendor/zbar/zbar/video/.deps/zbar_libzbar_la-vfw.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-processor.lo
/app/vendor/zbar/zbar/zbar_libzbar_la-image.lo
/app/vendor/zbar/zbar/zbar_libzbar_la-refcnt.o
/app/vendor/zbar/zbar/zbar_libzbar_la-error.o
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-qrdectxt.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-binarize.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-isaac.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-rs.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-qrdec.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-bch15_5.Plo
/app/vendor/zbar/zbar/qrcode/.deps/zbar_libzbar_la-util.Plo
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-video.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-config.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-processor.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-convert.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-window.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-refcnt.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-error.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-img_scanner.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-image.o
/app/vendor/zbar/zbar/.libs/zbar_libzbar_la-symbol.o
/app/vendor/zbar/zbar/zbar_libzbar_la-img_scanner.o
/app/vendor/zbar/zbar/zbar_libzbar_la-image.o
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-null.Plo
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-dib.Plo
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-xv.Plo
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-x.Plo
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-ximage.Plo
/app/vendor/zbar/zbar/window/.deps/zbar_libzbar_la-win.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-img_scanner.lo
/app/vendor/zbar/zbar/libzbar.rc
/app/vendor/zbar/zbar/zbar_libzbar_la-symbol.o
/app/vendor/zbar/zbar/zbar_libzbar_la-config.lo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-decoder.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-config.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-convert.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-processor.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-symbol.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-scanner.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-error.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-jpeg.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-video.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-window.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-refcnt.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-svg.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-img_scanner.Plo
/app/vendor/zbar/zbar/.deps/zbar_libzbar_la-image.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-window.lo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-code39.Plo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-pdf417.Plo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-qr_finder.Plo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-i25.Plo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-ean.Plo
/app/vendor/zbar/zbar/decoder/.deps/zbar_libzbar_la-code128.Plo
/app/vendor/zbar/zbar/zbar_libzbar_la-convert.lo

Has anyone had success getting zbar to run on heroku? If so, what buildpack did you use? I would be thrilled to learn how to make this work.


Solution

  • This is what ultimately worked for me:

    1) I needed to use the apt-buildpack and the ruby buildpack in tandem.

    Command line:

    heroku buildpacks
    https://github.com/ddollar/heroku-buildpack-apt
    https://github.com/heroku/heroku-buildpack-ruby
    

    2) Then I created a file called Aptfile (no extension), placed it at the root of my project folder, and the only line in it is:

    Aptfile:

    libzbar-dev
    

    Finally, I had to not require zbar in my gemfile, and require it separately in the code where I was processing the barcode:

    Gemfile:

    gem 'zbar', :require => false
    

    Controller:

    class HomeController < ApplicationController
      require 'zbar'
    
      def index
        path = "#{Rails.public_path}/barcode.jpg"
        jpeg = File.binread(path)
        z = ZBar::Image.from_jpeg(jpeg)
        r = z.process
        @barcode = r.first.data
      end
    end