Forum How do I...?

Fonts not found in aws lambda layer

vladcostea
Hi,

We're using princexml, linux version12.3, to render PDF documents.
We've installed prince in a lambda layer with all it's required libraries and env vars (LD_LIBRARY_PATH).
We're running the following prince command from a node.js process:
/opt/prince/bin/prince --debug --javascript --verbose --structured-log=normal /tmp/tmp.html -o /tmp/tmp.pdf


The /tmp/tmp.html file is written before running this command.

The PDF is generated fine, except if we use custom fonts (Roboto, Ubuntu, etc). For custom fonts, prince defaults to DejaVu.

I replicated the lambda environment in a docker container (as close to the real thing as possible), ran the same prince command from node.js, used the same env vars and libs and we were able to use custom fonts.

I've attached the debug output from the lambda run and the docker run.

On both environments we set the FONTCONFIG_PATH env var as /opt/fonts (lambda unzips layer files under /opt)

If I don't set this env var, prince complains that it can't find any fonts.
All the fonts are under /opt/fonts/<FontName> and there's also a /opt/fonts/fonts.conf file.
I also tried setting the FONTCONFIG_FILE to /opt/fonts/fonts.conf (again, works in our docker test and not in aws lambda layer)

I looked at https://www.freedesktop.org/software/fontconfig/fontconfig-user.html for info on these env vars and configs. I read that fontconfig looks in /etc/fonts/conf.d. That file is not present on the lambda layer nor on my docker image.

I tried looking up which version of fontconfig is installed without any luck.

I'm not really sure what else I can debug.

Thanks for your help and for a great product.
  1. docker_debug_output.txt4.6 kB
  2. lambda_debug_output.txt4.6 kB
keithfahlgren
It looks like you've already followed the fontconfig path suggested by https://stackoverflow.com/a/51622335, so an alternative approach might be to specify the fonts in CSS differently. Is that an option?

The Fonts section of the User Guide (https://www.princexml.com/doc-prince/#fonts) describes a variety of options, but in the past I've been happy with
url()
(although I haven't used it in Lambda yet). Something like:

    src: url("/opt/fonts/Raleway.otf")

vladcostea
Thanks for the quick reply.

I tried using url with this HTML:
<html>
<head>
<style>
@font-face {
  font-family: 'Raleway';
  src: url("/opt/fonts/Raleway/Raleway-Regular.ttf");
}
.raleway { font-family: 'Raleway', serif }
</style>
</head>
<body>
<div>Raleway in default</div>
<div class="raleway">Raleway in raleway</div>
</body>
</html>


Same result: works in my docker image, doesn't work in lambda:
msg|wrn|/opt/fonts/Raleway/Raleway-Regular.ttf|cannot open resource


I'll try to get a list of all the lambda env vars, maybe something with the setup is breaking this
vladcostea
I also tried with src: prince-lookup("Raleway");

I noticed debug statements with msg|dbg||font scan: Raleway, 0 matches.
When scanning for fonts, does prince use/need any env vars/config/cli params?
mikeday
This looks a bit suspicious, even if there is something wrong with the Fontconfig configuration there should be no problem loading the font from a fixed path specified with the @font-face rule, is there a way to confirm that the file /opt/fonts/Raleway/Raleway-Regular.ttf actually exists and is readable by the process?
vladcostea
Indeed it was as you said, not readable by the process.
I did a chmod 755 -R on my fonts folder and it was able to find the fonts after that.

Thanks a lot for the help