tpisto / pdf-fill-form

Fill PDF forms and return either filled PDF or PDF created from rendered page images.
MIT License
231 stars 48 forks source link

How can this library be used in AWS Lambda? #103

Open Newbie012 opened 3 years ago

Newbie012 commented 3 years ago

I tried to deploy a lambda function that uses this package. I was aware that I needed to install libcairo2-dev libpoppler-qt5-dev, but AFAIK, it's impossible to do so in AWS Lambda (correct me if I'm wrong). So of course, when I tested the function, I got the following error:

Error: libQt5Gui.so.5: cannot open shared object file: No such file or directory
    at ...
    at /opt/nodejs/node_modules/pdf-fill-form/lib/pdf-fill-form.js:70:43

which comes from: https://github.com/tpisto/pdf-fill-form/blob/a3996cdce2508060b221fcd60e9a1ee51d47d162/lib/pdf-fill-form.js#L70

I created a new layer with lib/libQt5Gui.so.5 inside, and then I got an error that libQt5Core.so.5 is missing and so on.

I eventually created this docker file:

FROM ubuntu:18.04

# Installing dependencies
RUN apt update
RUN apt-get update
RUN apt-get install -y locate \
                       libcairo2-dev \
                       libpoppler-qt5-dev

RUN rm -rf /poppler_binaries;  mkdir /poppler_binaries mkdir /poppler_binaries/lib;
RUN updatedb
RUN cp $(locate libQt5Gui.so.5) /poppler_binaries/lib/.
RUN cp $(locate libQt5Core.so.5) /poppler_binaries/lib/.
RUN cp $(locate libcairo.so.2) /poppler_binaries/lib/.
RUN cp $(locate libpoppler-qt5.so.1) /poppler_binaries/lib/.
RUN cp $(locate libGL.so.1) /poppler_binaries/lib/.
RUN cp $(locate libpng16.so.16) /poppler_binaries/lib/.
RUN cp $(locate libharfbuzz.so.0) /poppler_binaries/lib/.
RUN cp $(locate libicui18n.so.60) /poppler_binaries/lib/.
RUN cp $(locate libicuuc.so.60) /poppler_binaries/lib/.
RUN cp $(locate libdouble-conversion.so.1) /poppler_binaries/lib/.
RUN cp $(locate libglib-2.0.so.0) /poppler_binaries/lib/.
RUN cp $(locate libpixman-1.so.0) /poppler_binaries/lib/.
RUN cp $(locate libfontconfig.so.1) /poppler_binaries/lib/.
RUN cp $(locate libfreetype.so.6) /poppler_binaries/lib/.
RUN cp $(locate libxcb-shm.so.0) /poppler_binaries/lib/.
RUN cp $(locate libxcb.so.1) /poppler_binaries/lib/.
RUN cp $(locate libxcb-render.so.0) /poppler_binaries/lib/.
RUN cp $(locate libXrender.so.1) /poppler_binaries/lib/.
RUN cp $(locate libX11.so.6) /poppler_binaries/lib/.
RUN cp $(locate libXext.so.6) /poppler_binaries/lib/.
RUN cp $(locate libpoppler.so.73) /poppler_binaries/lib/.
RUN cp $(locate libQt5Xml.so.5) /poppler_binaries/lib/.
RUN cp $(locate libGLX.so.0) /poppler_binaries/lib/.
RUN cp $(locate libGLdispatch.so.0) /poppler_binaries/lib/.
RUN cp $(locate libgraphite2.so.3) /poppler_binaries/lib/.
RUN cp $(locate libicudata.so.60) /poppler_binaries/lib/.
RUN cp $(locate libpcre.so.3) /poppler_binaries/lib/.
RUN cp $(locate libexpat.so.1) /poppler_binaries/lib/.
RUN cp $(locate libXau.so.6) /poppler_binaries/lib/.
RUN cp $(locate libXdmcp.so.6) /poppler_binaries/lib/.
RUN cp $(locate libjpeg.so.8) /poppler_binaries/lib/.
RUN cp $(locate libnss3.so) /poppler_binaries/lib/.
RUN cp $(locate libsmime3.so) /poppler_binaries/lib/.
RUN cp $(locate liblcms2.so.2) /poppler_binaries/lib/.
RUN cp $(locate libtiff.so.5) /poppler_binaries/lib/.
RUN cp $(locate libbsd.so.0) /poppler_binaries/lib/.
RUN cp $(locate liblzma.so.5) /poppler_binaries/lib/.
RUN cp $(locate libjbig.so.0) /poppler_binaries/lib/.

But every time I got a different missing shared file. The layer has eventually grown up to 70MB and that's pretty much where I gave up (Yes, I manually deployed the layer 38 times. Yes, I know it's sad).

I know that this issue might be out of the scope of this package, but this issue might help other people (hopefully) that are trying to use this package in AWS Lambda.

nitsujri commented 2 years ago

As of early 2022, AWS Lambda can now run custom containers which means no more messing with layers!

Here's our working Dockerfile that is deployed in Lambda to help us fill PDFs. The build image is lifted from the aws-lambda-irc upgraded to node-14:

FROM node:14-buster-slim as build-image

# Include global arg in this stage of the build
ARG FUNCTION_DIR=/app

# Install aws-lambda-cpp build dependencies
RUN apt-get update && \
    apt-get install -y \
    g++ \
    make \
    cmake \
    unzip \
    libcurl4-openssl-dev \
    tar \
    gzip \
    autoconf \
    automake \
    libtool \
    libkrb5-dev \
    python3 \
    yarn \
    pkg-config \
    libpoppler-qt5-dev \
    libcairo2-dev

# Copy function code
RUN mkdir -p ${FUNCTION_DIR}
COPY . ${FUNCTION_DIR}

WORKDIR ${FUNCTION_DIR}

# If the dependency is not in package.json uncomment the following line
RUN npm install aws-lambda-ric

RUN yarn

# Grab a fresh slim copy of the image to reduce the final size
FROM node:14-buster-slim

# Include global arg in this stage of the build
ARG FUNCTION_DIR=/app

# Need some native functions so node modules work
RUN apt-get update && \
    apt-get install -y \
    pkg-config \
    libpoppler-qt5-dev \
    libcairo2-dev

# Set working directory to function root directory
WORKDIR ${FUNCTION_DIR}

# Copy in the built dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}

# ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"]
# CMD ["app.handler"]