I found a 4 year old project that's supposed to install phantomjs on lambda, but either I'm doing something wrong, or things have changed since the repo was created and it no longer works. When I clone and deploy this repository, I get this error trying to run phantomjs:
{
"errorType": "Error",
"errorMessage": "write EPIPE",
"code": "EPIPE",
"stack": [
"Error: write EPIPE",
" at WriteWrap.afterWrite [as oncomplete] (net.js:779:14)"
],
"errno": "EPIPE",
"syscall": "write"
}
{
"errorType": "Error",
"errorMessage": "html-pdf: Received the exit code '127'\n./phantomjs_lambda/phantomjs_linux-x86_64: error while loading shared libraries: libfreetype.so.6: cannot open shared object file: No such file or directory\n",
"stack": [
"Error: html-pdf: Received the exit code '127'",
"./phantomjs_lambda/phantomjs_linux-x86_64: error while loading shared libraries: libfreetype.so.6: cannot open shared object file: No such file or directory",
"",
" at ChildProcess.respond (/var/task/node_modules/html-pdf/lib/pdf.js:121:31)",
" at ChildProcess.emit (events.js:189:13)",
" at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)"
]
}
If I use the latest linux binary instead of the one that comes with this repo, I get a different but similar error about a different .so file missing.
For context, the reason I want to install phantomjs is because I want to use the node html-pdf library in my lambda.
I am on a Mac.
As an answer, I'm not looking to get past this specific error only to discover the next one. I'm looking for an answer that gets me a working phantomjs on aws lambda. If there is another node "html to pdf"/"html to png" library that doesn't require phantomjs to work and easily runs on AWS Lambda, that would be an acceptable solution, too.
For WindowsDownload the zip file, unpack it and you will get an executable phantom.exe. Set the PATH environment variable to the path of phantom.exe file. Open a new command prompt and type phantomjs –v. It should give you the current version of PhantomJS that is running.
One solution is to include the libraries required by PhantomJS in your Lambda function .zip file. I'll break this down into several steps.
Your error message states that a shared library is missing. Let's find exactly what PhantomJS is looking for by installing it in a Docker container and checking its runtime dependencies. The nodejs10.x AWS Lambda Runtime uses Amazon Linux 2, but the steps are similar for earlier runtimes.
On your host system, run an Amazon Linux 2 Docker container:
$ docker run -it --rm amazonlinux:2.0.20190508
In the container, install PhantomJS and inspect its dependencies:
bash-4.2$ yum install -y bzip2 tar
bash-4.2$ curl -LO https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
bash-4.2$ tar xf phantomjs-2.1.1-linux-x86_64.tar.bz2
bash-4.2# ldd ./phantomjs-2.1.1-linux-x86_64/bin/phantomjs
linux-vdso.so.1 (0x00007ffdd251f000)
libz.so.1 => /lib64/libz.so.1 (0x00007f35d0439000)
libfontconfig.so.1 => not found
libfreetype.so.6 => not found
...
We see that libfontconfig and libfreetype are missing.
Next, we'll download and extract the required libraries, then copy them to the host system. Note that libfontconfig depends on libexpat, so we'll install that as well.
In the container:
bash-4.2$ yum install -y yum-utils rpmdevtools
bash-4.2$ cd /tmp
bash-4.2$ yumdownloader fontconfig.x86_64 freetype.x86_64 expat.x86_64
bash-4.2$ rpmdev-extract *.rpm
Copy the libraries into a directory:
bash-4.2$ mkdir -p /deps
bash-4.2$ cp /tmp/*/usr/lib64/* /deps
Also copy the fontconfig configuration file:
bash-4.2$ cp /tmp/*/etc/fonts/fonts.conf /deps
Next, on the host, get the Docker container ID and copy the files from the container to the host. Below, lambda-node-phantom
is the directory where you cloned the https://github.com/TylerPachal/lambda-node-phantom repository:
$ cd lambda-node-phantom
$ docker ps
$ docker cp <CONTAINER_ID>:/deps/ .
$ mv deps/* . && rmdir deps
Update the PhantomJS binary in your directory to the version downloaded in the Docker container above. Make sure that index.js
refers to the correct name for the latest version; in version 2.1.1 it's named phantomjs
.
Next, add the following line to index.js
so that fontconfig finds fonts.conf
in the Lambda root directory:
process.env['FONTCONFIG_PATH'] = process.env['LAMBDA_TASK_ROOT'];
Finally, re-create the Lambda function .zip file, including the native libraries and font.conf
:
$ zip -y /path/to/lambda-node-phantom-dist.zip .
The -y
option stores symbolic links as links instead of the referenced file. To save space, make sure that the .git
directory is not included in the .zip file.
In the AWS Lambda console, upload the new Lambda function .zip file and test the Lambda function. PhantomJS should now run without errors, and your function should return "hello from phantom!" If not, check the stderr
returned by the PhantomJS child process for information.
It's likely that you'll need to modify fonts.conf
and/or include additional files for fonts to be rendered properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With