Automattic / node-canvas

Node canvas is a Cairo backed Canvas implementation for NodeJS.
10.2k stars 1.17k forks source link

Running under AWS Lambda (docker, Node 18): undefined symbol: pango_context_set_round_glyph_positions #2250

Open jameshalsall opened 1 year ago

jameshalsall commented 1 year ago

Issue or Feature

When deploying to AWS lambda using a Docker image we encounter the following error:

/var/lang/bin/node: symbol lookup error: /var/task/node_modules/canvas/build/Release/canvas.node: undefined symbol: pango_context_set_round_glyph_positions

I believe this is related to the changes made here. It worked in version 2.11.0 without issue.

In the base image I am building from (https://gallery.ecr.aws/lambda/nodejs) we can see the version of pango is < 1.44.0, but for some reason the following condition evaluates to true when canvas is compiled:

From canvas src/CanvasRenderingContext2d.cc:

#if PANGO_VERSION_CHECK(1, 44, 0)
  pango_context_set_round_glyph_positions(pango_layout_get_context(_layout), FALSE);
#endif

Version on the AWS Lambda image:

bash-4.2# pango-view --version
pango-view (pango) 1.42.3

So I am a bit confused as to why the pango_context_set_round_glyph_positions call is being compiled in the canvas target.

--

Steps to Reproduce

Example Dockerfile:

FROM --platform=linux/amd64 public.ecr.aws/lambda/nodejs:18

RUN yum -y update \
      && yum -y groupinstall "Development Tools" \
      && yum install -y nodejs gcc-c++ cairo-devel \
                          libjpeg-turbo-devel pango-devel giflib-devel \
                          zlib-devel librsvg2-devel

COPY package.json ${LAMBDA_TASK_ROOT}
COPY yarn.lock ${LAMBDA_TASK_ROOT}

RUN npm install -g yarn
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install

COPY dist ${LAMBDA_TASK_ROOT}/dist

RUN yum remove -y cairo-devel libjpeg-turbo-devel \
        pango-devel giflib-devel zlib-devel librsvg2-devel

ENV LD_PRELOAD=/var/task/node_modules/canvas/build/Release/libz.so.1

CMD [ "dist/example.execute" ]

dist/example.js:

import canvas from 'canvas';

export const execute = async (event, context) => {
  var ctx = canvas.createCanvas(200, 200).getContext('2d');
};

Your Environment

rish-norma commented 1 year ago

@jameshalsall Did you solve it by any chance? Thanks.

jameshalsall commented 1 year ago

Unfortunately not. We just downgraded to an older version of node-canvas 😞

micahkatz commented 1 year ago

Unfortunately not. We just downgraded to an older version of node-canvas 😞

What version did you end up downgrading to?

jameshalsall commented 1 year ago

2.11.0

rorueda commented 11 months ago

This is probably happening because canvas is not being built from source - by default a pre-built canvas is downloaded.

I managed to make it work by running npm install --build-from-source=canvas.

You will also need to install python3 and to keep cairo, libjpeg, etc. or copy them to ../canvas/build/Release. And you won't need LD_PRELOAD.