I am trying to get my lambda function to use phantomjs, however it keeps running into an error of a missing dependency: libfontconfig / fontconfig. On my Centos VPS when I install fontconfig (dnf install fontconfig -y) my code works fine. However when running on lambda I cannot figure out how to get this library to be ran with my function.
This is my code: (Attempting to get the best selling products through the AliExpress package, which uses phantomjs)
const aliExpress = require('aliexpress');
exports.handler = (event, context, callback) => {
console.log('Handler ran!');
aliExpress.BestSelling.get().then((goods) => {
console.log('Found results!');
const urls = [];
for(let index in goods) {
const url = goods[index].url;
urls.push(url);
}
console.log('Returning URLs:');
console.log(urls);
callback(null, urls);
}).catch((err) => {
console.log('Error:');
console.log(err);
callback(err);
});
};
// For testing on VPS
exports.handler(null, null, (err, result) => {
if(err) {
console.log('Err:');
console.log(err);
} else {
console.log('Result:');
console.log(result);
}
});
I am expecting the result to be an array of AliExpress URLs, this is what happens whenever I run it with fontconfig installed on my VPS. However, on my lambda function AND on my VPS without fontconfig installed I am getting this error:
Handler ran!
(node:1966) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Error reading from stdin: Error: write EPIPE
(node:1966) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
error: /home/function/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
I believe I now either have to 1) Figure out how to run phantomjs without this dependency or 2) Figure out how to install this dependency to my Lambda function's "server"
Perhaps there's a previous version of phantomjs that gives me the functionality I want without this dependency? Not sure
Anyone know how I can solve this problem? Thank you!
Using phantom js on lambda with nodejs 10 and 12 is not directly possible, it becase it misses few dependencies like libfontconfig.so on the newer amazon linux 2 base image. To overcome this problem you have to use your own fonts folder which contains the required files and a font.conf file
If you want to add fonts in AWS Lambda V2 as it does not appear to support even the basic fonts on its own, create a directory called “/fonts” on your distribution package and include the fonts.conf inside the folder (this is a very stripped version):
I receive the "Unable to import module" error when I try to run my AWS Lambda code in Python. You typically receive this error when your Lambda environment can't find the specified library in the Python code. This is because Lambda isn't prepackaged with all Python libraries.
Create an AWS Identity and Access Management (IAM) role with permissions to call the publish-layer-version API. Then, attach the IAM role to the EC2 instance. Note: Your EC2 instance now has permissions to upload Lambda layers for the publish-layer-version API call.
Here's what I just got to work for custom fonts on AWS Lambda with pandoc/xelatex. I'd bet you can adapt it to do something similar for your use case.
I created a fonts
directory in my project and placed all of my fonts there. Also in that directory I created a fonts.conf
file that looks like this:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/var/task/fonts/</dir>
<cachedir>/tmp/fonts-cache/</cachedir>
<config></config>
</fontconfig>
And then in my (node.js based) handler function before shelling out to call pandoc I set an ENV var to tell fontconfig where to find the fonts.
process.env.FONTCONFIG_PATH='/var/task/fonts'
After doing that I can refer to a font, like Bitter
, in my template by name (just Bitter
) and then pandoc/xelatex/fontconfig/whatever knows which version of the font to use (like Bitter-Bold.otf
vs Bitter-Italic.otf
) based on the styling that any bit of text is supposed to have.
I figured this out based on the tips in this project for getting RSVG to work with custom fonts on Lambda: https://github.com/claudiajs/rsvg-convert-aws-lambda-binary/blob/master/README.md#using-custom-fonts
For those ending up there, here's my little story: I wanted to use a Roboto font to generate html-template-based PDF with phantomJs on a AWS Lambda execution.
My application 'App' is in nodeJs and depends on a 'RunTimeDep' dependency which executes a bunch of useful stuff for App at runtime. Among those tasks, it generates a PDF based on a html template, in which I wanted to use Roboto Mono. Just to mention, the html template is in 'App'.
To do so, I created the /fonts folder as @Jeremy Green mentionned in the 'RunTimeDep' module. I converted the Roboto fonts into PFB format, and put them there. I added thus this fonts.conf:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/var/task/node_modules/RunTimeDep/fonts/</dir>
<cachedir>/tmp/fonts-cache/</cachedir>
<config></config>
</fontconfig>
Finally, I added the FONTCONFIG_PATH to point to /var/task/node_modules/RunTimeDep/fonts/ (I used serverless envrionment variable, but process.env should be fine too)
And this actually worked just great
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