Google Cloud Functions and shared libraries
Asked Answered
P

3

6

I'm trying to use wkhtmltopdf on GCF for PDF generation. When my function tries to spawn the child process I get the following error:

Error: ./services/wkhtmltopdf: error while loading shared libraries: libXrender.so.1: cannot open shared object file: No such file or director

The problem is clearly due to the fact that wkhtmltopdf binary depends on external shared libraries which are not installed in GCF environment.

Is there a way to solve this issue or should I give up and use other solutions (AWS Lambda o GAE)? Thank you in advance

Pavlov answered 9/10, 2017 at 5:18 Comment(3)
I am facing the exact same issue. As far as I know there is currently no way to execute anything else but JS in the GCF-environment.Cabinetwork
Same for Microsoft Azure Functions...Verlie
Hey i really would love to do that too, can you maybe publish your solution on GitHub?Debouch
P
0

Indeed, I’ve found a way to solve this issue by copying all required libraries in the same folder (/bin for me) containing wkhtmltopdf binary. In order to let the binary file use uploaded libraries I added the following lines to wkhtmltopdf.js: wkhtmltopdf.command = 'LD_LIBRARY_PATH='+path.resolve(__dirname, 'bin')+' ./bin/wkhtmltopdf'; wkhtmltopdf.shell = '/bin/bash'; module.exports = wkhtmltopdf;

Everything worked fine for a while. At a sudden I receive many connection errors from GCF or timeouts but I think it’s not related to my implementation but rather to Google. I’ve ended up setting a dedicated server.

Pavlov answered 4/1, 2018 at 16:18 Comment(0)
W
0

I have managed to get it working, there are 2 things needed to be done, as wkhtmltopdf won't work if:

  • libXrender.so.1 can't be loaded
  • you are using stdout to collect resulting pdf. Wkhtmltopdf has to write the result into a file

First you need to obtain correct version of libXrender.
I have found out, which docker image Cloud functions are using as base for nodejs functions. I've ran it locally, installed libxrender and copied the library into my function's directory.
docker run -it --rm=true -v /tmp/d:/tmp/d gcr.io/google-appengine/nodejs bash
Then, inside the runing container:

apt update
apt install libxrender1
cp /usr/lib/x86_64-linux-gnu/libXrender.so.1 /tmp/d

I have put this into my function's project directory and under lib sub directory. In my function's source file, I then set-up LD_LIBRARY_PATH to include the /user_code/lib directory (/user_code is the directory, where at last your function will end up being put by google):
process.env['LD_LIBRARY_PATH'] = '/user_code/lib'

This is enough for wkhtmltopdf to be able to execute. It will fail, as it won't be able to write to stdout and the function will eventually timeout and be killed (as Matteo experienced). I think this is because google runs the containers without a tty (just speculation), I can run my code in their container, if I run it with docker run -it flags. To solve this, I am invoking wkhtmltopdf so that it writes the output into a file under /tmp (this is in-memory tmpfs). I then read the file back and send it as my response body. Note that the tmpfs might be reused between function calls, so you need to use unique file every time.

This seems to do the trick and I am able to run wkhtmltopdf as Google CloudFunction.

Wareroom answered 9/5, 2018 at 12:2 Comment(0)
W
0

If you want to use wkhtmlopdf on google functions, I would recommend using Ruby language because it provides a library

  1. https://github.com/mileszs/wicked_pdf
  2. https://github.com/zakird/wkhtmltopdf_binary_gem - This is binary for all the supported OS.

Google provides Ubuntu OS for functions & this binary gem has that QT package.A sample code looks like this:

require 'functions_framework'

FunctionsFramework.http "generate_pdf" do |request|
  require 'wicked_pdf'

  WickedPdf.config = {
    exe_path: "#{Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')}",
    enable_local_file_access: true
  }

  pdf = WickedPdf.new.pdf_from_string('<h1>Hello There!</h1>')
  return { pdf: pdf }
end
Walworth answered 26/6, 2023 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.