Loskir / styled-qr-code

Automaticly generate your styled QR code in your web app.
https://qr-code-styling.com
MIT License
40 stars 23 forks source link

Issue Using @loskir/styled-qr-code-node in AWS Lambda Function #11

Closed emblaszkiewicz closed 1 month ago

emblaszkiewicz commented 1 month ago

I want to use the package @loskir/styled-qr-code-node in an AWS Lambda function, but I have encountered an issue that I don't know how to resolve. This package uses skia-canvas, and from what I understand, the latest version of skia-canvas requires GLIBC_2.27. However, the current AWS Lambda Node.js images only support GLIBC_2.26, as I checked inside the Docker container.

Does anyone have any ideas on how I can make this work and use this package in AWS Lambda functions?

emblaszkiewicz commented 1 month ago

I solved this Issue by using public.ecr.aws/lambda/nodejs:20 image and install skia-canvas and fontconfig inside the container in the second stage of building.

MATTiVOLTARii commented 4 days ago

I solved this Issue by using public.ecr.aws/lambda/nodejs:20 image and install skia-canvas and fontconfig inside the container in the second stage of building.

I have the same problem. Could you go into more detail or share your dockerfile? Would be great!

emblaszkiewicz commented 4 days ago

Unfortunately, I can't share my Dockerfile, but I can help you with yours. Could you provide me with more details? Are you using multi-stage builds in your Dockerfile? Which base image are you using?

MATTiVOLTARii commented 4 days ago

Thanks to your @emblaszkiewicz suggestion involving a multi-stage build process, I managed to successfully resolving the issue related to libfontconfig for deploying with AWS Lambda, build and run skia-canvas with all necessary dependencies. I wanted to share the solution that may help others facing similar challenges. Here's the step-by-step guide and a Dockerfile that, while potentially improvable, worked for me. Here’s my pretty rookie solution, starting with the dockerfile:

# Stage 1: Build Node Modules
FROM public.ecr.aws/lambda/nodejs:20 AS builder

# Install required libraries
RUN dnf install -y \
    fontconfig \
    freetype \
    libpng \
    libjpeg-turbo \
    zlib \
    librsvg2 \
    harfbuzz \
    brotli \
    cairo \
    pango \
    glib2 \
    gdk-pixbuf2 \
    gcc-c++ \
    make \
    tar gzip && dnf clean all

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install skia-canvas and other dependencies
RUN npm install skia-canvas

# Stage 2: Prepare the Final Image for AWS Lambda
FROM public.ecr.aws/lambda/nodejs:20

# Install necessary libraries for runtime
RUN dnf install -y \
    fontconfig \
    freetype \
    libpng \
    libjpeg-turbo \
    zlib \
    librsvg2 \
    harfbuzz \
    brotli && dnf clean all

# Copy Node modules and compiled dependencies from the builder stage
COPY --from=builder /app/node_modules /app/node_modules
COPY --from=builder /usr/lib64/* /opt/lib/

# Copy the project source code
COPY . /app

# Set the working directory
WORKDIR /app

# Define the Lambda function handler
CMD ["index.handler"]

Build and Extract Libraries

  1. Build the Docker image:
    docker build -t lambda-container .
  2. Run the container:
    docker run -d --name lambda-container lambda-container
  3. Access the container shell:
    docker exec -it lambda-container /bin/bash
  4. Copy necessary libraries from the container to the host:
    docker cp lambda-container:/usr/lib64 ./native-libs

Required Libraries for Lambda Layer

Copy the following libraries (or others as needed) from the native-libs folder into a lib directory:

Create and Deploy the Lambda Layer

  1. Zip the lib folder:
    zip -r lib-layer.zip lib
  2. Upload the zipped lib folder as an AWS Lambda layer.
  3. Set the environment variable in your Lambda function:
    process.env.LD_LIBRARY_PATH = "/opt/lib";

By following this guide, you should be able to deploy your Node.js application with skia-canvas and its dependencies on AWS Lambda.