Different output wkhtmltopdf local and on heroku - ruby-on-rails

On my Macbook I have wkhtmltopdf installed and when I do wkhtmltopdf -V I get:
wkhtmltopdf 0.12.2.1 (with patched qt)
When I deploy the Rails app to Heroku, the PDF renders different. So I checked the version on Heroku with heroku run "wkhtmltopdf -V", but that gives me:
bash: wkhtmltopdf: command not found.
The PDF itself renders fine on Heroku, so there must be a wkhtmltopdf installed I guess? I followed these instructions to create a buildpack, but with no change when I request the version:
https://elements.heroku.com/buildpacks/rafaelp/heroku-buildpack-wkhtmltopdf
In the Gemfile I have this:
group :development do
gem 'wkhtmltopdf-binary-edge', '~> 0.12.2.1'
end
So, how do I properly install wkhtmltopdf on Heroku and make sure the version is the same as on my Macbook?

You're probably seeing a conflict in versions here between a binary bundled in the gem you're using in development, and another binary.
You should manually manage your wkhtmltopdf binary manually in development & heroku (homebrew/apt-get + buildpack), or use a gem which includes the binaries in both environments. Not a mix of both, as you'll get inconsistent results.
Personally, I use this buildpack on heroku and use brew to install the version I need locally for development.

Related

Rails bundle error when pushing to Elastic Beanstalk

I had an app deployed on Heroku and I am currently trying to create the same app on AWS.
I've copied my folder, created a complete separated repo on Github and installed ebcli, the setup looks fine.
When I try to run eb deploy, I have this error:
[Instance: i-03051e2a022886184] Command failed on instance. Return code: 1 Output: (TRUNCATED)...:in find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
from /opt/rubies/ruby-2.5.3/lib/ruby/site_ruby/2.5.0/rubygems.rb:308:inactivate_bin_path'
from /opt/rubies/ruby-2.5.3/bin/bundle:23:in `'.
I've looked online and it says it comes from incompatibility between your gemlock file bundler version and actual bundler version.
I've tried to change my bundler version to this one, but I gave up and came back to 2.0.1 because I had to install too many dependencies otherwise.
I removed the gemlock, bundle again, but I still got the same error when trying to deploy.
With my heroku version, it always worked.
Any idea how to solve that?
Thanks a lot
We moved from Heroku to AWS a few months back as well and it will likely take some some custom scripting to get things to work.
It would help to know more about your EB environment, but I am assuming you are using Ruby 2.5 with Puma on Amazon Linux 2.9.0 (?)
Not sure what bundle version comes with that, But I don’t think it’s 2.x. so you have to add an .ebextensions file too install your preferred bundled version.
# .ebextensions/01_install_bundler.config
container_commands:
install_bundler:
command: “gem install bundler —-version 2.0.0”
More info on AWS Linux customizations
End of the day, we are much happier with our AWS environment (lower cost, better performance), but requires more work to get it set up
Actually the problem exists because the bundler version in the eb env is older than the one being used in the project source.
So the solution is to use a bundler version less or equal the eb env installed version.
First uninstalled the current bundler:
gem uninstall bundle
and then install the desired one:
gem install bundler -v 1.16.6
See more details

Where are Ruby gems located on a server?

My understanding is that the gemfile in a Rails app only provides references to the actual code of these gems on your local computer. So when you're running your app locally, it's pulling the gem code from your local computer. What happens when you deploy though? The server runs your rails code, but does it also hold all the references in your gem file and automatically download them as well?
Yep. If you deploy on Heroku, you can see bundler doing its work and pulling down the gems.
As per the Bundler docs, you can use bundle show --paths to see exactly where your gems are being loaded from.
Additionally, if you aren't using bundler, you can use the command gem environment to see gem paths on the system.
See this existing answer for more info: How can I find where gem files are installed?

Deploying error with capistrano: "bundler: not executable: cap"

I am supposed to work on a quite antique Ruby On Rails project to make some minor (mostly HTML and CSS) changes on some webpages. I did not work with Ruby On Rails before and I am just getting into it.
I have cloned the project via git from github and installed all gems via 'bundler install'. Note that I am using an old version of Ruby (1.8.7) since I was told the project would not work with a newer version. Note also I am on Windows 7 and the project was built with Mac OS X.
Now I am trying to get the changes I made to the live site (after commiting and pushing the changes to the git repository) with Capistrano (Installed and Version 2.8.0) which should be possible with
bundle exec cap production deploy
However when I try this I just get:
bundler: not executable: cap
Any ideas what is going wrong here? Thanks alot in advance!
Kind regards,
Peter
Generally, capisrano is not defined as a gem in a project's Gemfile. Try installing the gem with gem install capistrano.
You can also check if Capistrano is installed on your system by running cap -T in your project folder. This should give you a list of all tasks in that project.

wkhtmltopdf is not executable from wicked-pdf within war

I am trying to create a pdf using wicked-pdf from Ruby On Rails. It works great in development mode, but when I deploy in production I get the error:
wkhtmltopdf is not executable
I have the wkhtmltopdf executable located at:
rails_root/bin/wkhtmltopdf-i386
Warbler is setup to include the bin folder in the war:
config.includes = FileList["classes/*","bin/*"]
I have wicked pdf configured to find the bin in the correct spot:
WickedPdf.config = {
:exe_path => Rails.root.join('bin', 'wkhtmltopdf-i386').to_s
}
I run warbler and then deploy the war on jBoss application server. When I try to generate a PDF I get the error about it not being executable. It runs fine in development mode - not in a war.
The permissions on the binary should be fine:
-rwxr-xr-x 1 username group 11446024 Apr 3 11:40 wkhtmltopdf-i386
Instead of manually including the wkhtmltopdf binary, I tried using wkhtmltopdf-binary gem. This too worked fine in development mode, but Wicked PDF can't find the binary in production.
Update: I changed the wicked-pdf config to point to the binary provided by 'wkhtmltopdf-binary' gem when in production mode. It also is getting wkhtmltopdf is not executable error. The path ends up being: jboss-5.1.0.GA/server/default/tmp/3j001-3g0fg5-hf2xi49o-1-hf2xiuld-9q/myrailsapp.war/WEB-INF/gems/gems/wkhtmltopdf-binary-0.9.9.1/bin/wkhtmltopdf_linux_386
Do you install wkhtmltopdf separately or allow your gem file to install it?
I'd do the following:
gem 'wicked_pdf', '~> 0.9.10'
gem 'wkhtmltopdf-binary', '~> 0.9.9'
and then set the config:
WickedPdf.config = {
exe_path: "#{ENV['GEM_HOME']}/gems/wkhtmltopdf-binary-#{Gem.loaded_specs['wkhtmltopdf-binary'].version}/bin/wkhtmltopdf_linux_386"
}
This bit #{Gem.loaded_specs['wkhtmltopdf-binary'].version} queries your gems to find the current version if you were to ever change the version of the gem, your prod server would still be able to find the proper folder.
I faced this same issue when working with a Rails 5.2.3 application on an Ubuntu 18.04.
The error displayed is this:
Gem::Exception: can't find executable wkhtmltopdf for gem wkhtmltopdf-binary. wkhtmltopdf-binary is not currently included in the bundle, perhaps you meant to add it to your Gemfile?
Here's how I solved it:
I simply added the wkhtmltopdf-binary gem to the production group which already had the wkhtmltopdf-heroku in the Gemfile.
group :production do
gem 'wkhtmltopdf-heroku'
gem 'wkhtmltopdf-binary'
end
And then installed the gem
bundle install --without development test
If you're running on a production server, please endeavour to install the libxrender1 library, since it's a dependency for wkhtmltopdf (for rendering PDFs), to avoid en error when rendering PDFs.
sudo apt-get install libxrender1
That's all.
I hope this helps

Using Hunspell With Heroku

I'm building a Rails app that uses Hunspell and the hunspell-ffi gem so that Ruby can interface with it. I'm deploying the app to heroku, but unfortunately it needs Hunspell to be installed on the server in order for the gem to work.
Is there any way for me to install Hunspell on Heroku? Or am I going to have to migrate to EC2?
Thanks in advance :)
You need to build the required Hunspell library and include it in your Heroku project directly.
Heroku runs on 64-bit Ubuntu therefore the binary has to be compiled under that system. The best approach is to simply use Heroku's Vulcan build server to compile on a Heroku instance.
Compiling for Heroku
gem install vulcan
vulcan create vulcan-compile-me last argument is your own app name.
Download Hunspell source
Extract
vulcan build -v -s ./hunspell-1.3.2 Tells Vulcan to build it and downloads the finished product automatically to /tmp/hunspell..
The build server requires the cloudant add-on, this is installed automatically but you have to make sure to have a verified (credit card added) Heroku account. If you get errors in step six of no build output then do heroku addons:add cloudant --app vulcan-compile-me
Adding to Your Project
Extract the Heroku Vulcan build tar from /tmp
Copy the entire lib folder to vendor/hunspell in your project root directory
Tell Heroku where to look for libraries: heroku config:add LD_LIBRARY_PATH=vendor/hunspell/lib.
Install Dictionaries
Download some dictionaries from Open Office and add them to your project. A good location is a folder called dictionaries at root level. This path is then referenced when initializing Hunspell in Ruby.
http://extensions.services.openoffice.org/dictionary
ftp://sunsite.informatik.rwth-aachen.de/pub/mirror/OpenOffice/contrib/
Using
Install your favorite Hunspell gem, I use hunspell-ffi. There is a newer gem for Hunspell but I prefer the previous FFI gem. To use initialize the Hunspell object with your dictionaries folder path and language (language match the dictionary file name).
dict = Hunspell.new("dictionaries", "en_US")
if dict.check('caribean') == false
suggestions = dict.suggest('caribean')
if (suggestions.size)
correction = suggestions.first # returns 'caribbean'
end
end
Vendoring for More Complex Projects
You can also vendor the library into your project by putting the tar built by the Vulcan server in the first step into a public accessible server such as Google Storage and then changing the Heroku build pack to download the tar on each instance startup.
heroku config:set BUILDPACK_URL=https://github.com/peterkeen/heroku-buildpack-vendorbinaries.git
The vendor build pack looks for a .vendor_urls file at the root level with HTTP links to the tar balls to install (needs to end in a new line to work).
http://commondatastorage.googleapis.com/developer.you.com/hunspell-heroku-1.3.tgz
Vendoring unpacks the tar into the root folder so the lib path for the Heroku settings would then just be "lib". heroku config:add LD_LIBRARY_PATH=lib
Unless I am mistaken or something has changed (I cannot find any evidence of this), you cannot install external native libraries on Heroku. If the library is not already installed (this is the case, I think, for ImageMagick, and perhaps others), you will not be able to use the gem.
Checkout this url: http://gems-summary.heroku.com/2011-07-19
It's freaking amazing how much support Heroku has for the gem community. So all you need to to is add the gem to your bundle since Hunspell is on rubygems, bundle install, and then deploy.
Gemfile
source 'http://rubygems.org'
gem 'rails', '3.0.5'
gem 'hunspell'
Then add to git:
git add .
git commit -m 'added hunspell'
Then bundle:
bundle
And deploy:
git push heroku
With Bundler, you should be able to install any gem. According to http://devcenter.heroku.com/articles/how-do-i-install-gems-for-my-app, "Almost any gem - even those with native dependencies - can be installed using Bundler. If there’s a specific gem that won’t install on Heroku, please submit a support ticket."
AFAIK, when your app is spun up, gems in the Gemfile are installed on-the-fly to the server your app is spun up to.
The Aspen stack has pre-installed gems, but you still should be able to add gems not pre-installed.
The bamboo stack has no pre-installed gems, so all gem dependencies must be declared explicitly. I believe that is the same for the Celadon stack.

Resources