Home > Software design >  how to install puppeteer for AWS lambda inside docker?
how to install puppeteer for AWS lambda inside docker?

Time:09-15

i'm trying to generate pdf file for this service i'm building with typescript. now everything works locally but i can't deploy it to AWS as it exceeds the lambda limit. now i am trying to dockerize it and it get's deployed but throws the following error.

"Failed to launch the browser process!\n/var/task/node_modules/puppeteer/.local-chromium/linux-1036745/chrome-linux/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory\n\n\nTROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md\n"

this is where it fails

const browser = await puppeteer.launch({
    headless: false,
    args: args,
    ignoreDefaultArgs: ['--disable-extensions'],
    executablePath: '/usr/bin/chromium-browser',
  });

  const page = await browser.newPage();

and here is my Dockerfile

FROM public.ecr.aws/lambda/nodejs:14.2022.09.09.11
ARG FUNCTION_DIR="/var/task"

# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy package.json
COPY package.json ${FUNCTION_DIR}

# Install NPM dependencies for function
RUN npm install

# Copy handler function and tsconfig
COPY . ${FUNCTION_DIR}

# Compile ts files
RUN npm run build

# Set the CMD to your handler
CMD [ "dist/src/generate.pdf" ]

CodePudding user response:

i did a workaround from here so i changed my Dockerfile as below

FROM node:latest
RUN apt-get install -y \
    fonts-liberation \
    gconf-service \
    libappindicator1 \
    libasound2 \
    libatk-1.0\
    libatk1.0-0 \
    libcairo2 \
    libcups2 \
    libfontconfig1 \
    libgbm-dev \
    libgdk-pixbuf2.0-0 \
    libgtk-3-0 \
    libicu-dev \
    libjpeg-dev \
    libnspr4 \
    libnss3 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libpng-dev \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    xdg-utils \
    chromium-browser

FROM public.ecr.aws/lambda/nodejs:14.2022.09.09.11
ARG FUNCTION_DIR="/var/task"

# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy package.json
COPY package.json ${FUNCTION_DIR}

# Install NPM dependencies for function
RUN npm install

RUN chmod -R o rwx node_modules/puppeteer/.local-chromium


# Copy handler function and tsconfig
COPY . ${FUNCTION_DIR}

# Compile ts files
RUN npm run build

# Set the CMD to your handler
CMD [ "dist/src/generate.pdf" ]

and my code as below

export async function generatePdf(
  file: FileType,
  options?: OptionsProps,
  callback?: CallBackType
) {
  let args = [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
  ];

  if (options?.args) {
    args = options.args;
    delete options.args;
  }

  const browser = await puppeteer.launch({
    args: args,
    executablePath: '/usr/bin/google-chrome',
  });

  const page = await browser.newPage();

now i'm getting another error

"Failed to launch the browser process! spawn /usr/bin/google-chrome ENOENT\n\n\nTROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md\n"

if i remove the executablePath: '/usr/bin/google-chrome' then still getting error but diffferent one

"Failed to launch the browser process!\n/var/task/node_modules/puppeteer/.local-chromium/linux-1036745/chrome-linux/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory\n\n\nTROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md\n"

CodePudding user response:

then i tried another solution from here

my Dockerfile

FROM node:17-alpine
ENV CHROME_BIN="/usr/bin/chromium-browser" \
    PUPPETEER_SKIP_CHROMIUM_DOWNLOAD="true"
RUN set -x \
    && apk update \
    && apk upgrade \
    && apk add --no-cache \
    udev \
    ttf-freefont \
    chromium \
    && npm install puppeteer

FROM public.ecr.aws/lambda/nodejs:14.2022.09.09.11
ARG FUNCTION_DIR="/var/task"

# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy package.json
COPY package.json ${FUNCTION_DIR}

# Install NPM dependencies for function
RUN npm install

RUN chmod -R o rwx node_modules/puppeteer/.local-chromium


# Copy handler function and tsconfig
COPY . ${FUNCTION_DIR}

# Compile ts files
RUN npm run build

# Set the CMD to your handler
CMD [ "dist/src/generate.pdf" ]

and my code

export async function generatePdf(
  file: FileType,
  options?: OptionsProps,
  callback?: CallBackType
) {
  let args = [
    '--no-sandbox',
    '--headless',
    '--disable-gpu',
    '--disable-dev-shm-usage',
  ];

  if (options?.args) {
    args = options.args;
    delete options.args;
  }

  const browser = await puppeteer.launch({
    headless: true,
    args: args,
    executablePath: '/usr/bin/chromium-browser',
  });

  const page = await browser.newPage();

and now i get the following error

"Failed to launch the browser process! spawn /usr/bin/chromium-browser ENOENT\n\n\nTROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md\n"

CodePudding user response:

i, then found another solution here

so i changed my Dockerfile

FROM kinlan/puppets:latest

# Copy the app
COPY . /app/
#COPY local.conf /etc/fonts/local.conf
WORKDIR app
RUN npm i && npm run build

# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser ./node_modules

# Run everything after as non-privileged user.
USER pptruser

EXPOSE 8084
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/src/generate"]

and my code as same before

const browser = await puppeteer.launch({
    headless: true,
    args: [
    '--no-sandbox',
    '--headless',
    '--disable-gpu',
    '--disable-dev-shm-usage',
  ];,
    executablePath: '/usr/bin/chromium-browser',
  });

and now i get a different error

START RequestId: 798fff12-3289-4a8b-90b4-72b724506f67 Version: $LATEST
/app/node_modules/puppeteer/lib/cjs/puppeteer/common/util.js:366
for await (const chunk of readable) {
^^^^^
SyntaxError: Unexpected reserved word
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:607:28)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/BrowserConnector.js:42:19)
END RequestId: 798fff12-3289-4a8b-90b4-72b724506f67

CodePudding user response:

now i have tried another solution from here

my Dockerfile

FROM public.ecr.aws/lambda/nodejs:14

RUN yum install -y wget unzip libX11

RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm && \
    yum install -y google-chrome-stable_current_x86_64.rpm

RUN CHROME_DRIVER_VERSION=`curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE` && \
    wget -O /tmp/chromedriver.zip https://chromedriver.storage.googleapis.com/$CHROME_DRIVER_VERSION/chromedriver_linux64.zip && \
    unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/

ARG FUNCTION_DIR="/var/task"

# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy package.json
COPY package.json ${FUNCTION_DIR}

# Install NPM dependencies for function
RUN npm install

# Copy handler function and tsconfig
COPY . ${FUNCTION_DIR}

# Compile ts files
RUN npm run build

# Set the CMD to your handler
CMD [ "dist/src/generate.pdf" ]

and my code

export async function generatePdf(
  file: FileType,
  options?: OptionsProps,
  callback?: CallBackType
) {
  let args = [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',
    '--disable-gpu',
  ];

  if (options?.args) {
    args = options.args;
    delete options.args;
  }

  const browser = await puppeteer.launch({
    args: args,
    executablePath: '/usr/bin/google-chrome',
  });

and i get this error "Protocol error (Target.setAutoAttach): Target closed."

2022-09-15T05:46:28.039Z    a251301b-87b7-4e34-bf7c-c1d0a42ae6f5    ERROR   ProtocolError: Protocol error (Target.setAutoAttach): Target closed.
    at /var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:104:24
    at new Promise (<anonymous>)
    at Connection.send (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Connection.js:100:16)
    at ChromeTargetManager.initialize (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/ChromeTargetManager.js:253:82)
    at Browser._attach (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Browser.js:219:73)
    at Function._create (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/common/Browser.js:201:23)
    at ChromeLauncher.launch (/var/task/node_modules/puppeteer/lib/cjs/puppeteer/node/ChromeLauncher.js:92:50)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async generatePdf (/var/task/dist/src/helpers/makePdf.js:21:21)
    at async Runtime.pdf [as handler] (/var/task/dist/src/generate.js:21:29) {
  originalMessage: ''
}
  • Related