繁体   English   中英

如何在 docker 中为 AWS lambda 安装 puppeteer?

[英]how to install puppeteer for AWS lambda inside docker?

我正在尝试为我正在使用 typescript 构建的此服务生成 pdf 文件。 现在一切都在本地工作,但我无法将它部署到 AWS,因为它超过了 lambda 限制。 现在我正在尝试对其进行 dockerize 并部署它,但会引发以下错误。

"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"

这是失败的地方

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

  const page = await browser.newPage();

这是我的 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" ]

我从这里做了一个解决方法,所以我改变了我的 Dockerfile 如下

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" ]

我的代码如下

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();

现在我又遇到了另一个错误

"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"

如果我删除了executablePath: '/usr/bin/google-chrome'那么仍然会出现错误但不同的一个

"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"

然后我从这里尝试了另一种解决方案

我的 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" ]

和我的代码

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();

现在我收到以下错误

"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"

我,然后在这里找到了另一个解决方案

所以我改变了我的 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"]

我的代码和以前一样

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

现在我得到一个不同的错误

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

现在我从这里尝试了另一种解决方案

我的 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" ]

和我的代码

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',
  });

我收到此错误"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: ''
}

更新了我的 Dockerfile 我正在使用构建并复制到我自己的构建

ARG FUNCTION_DIR="/function"
FROM node:slim as build-image
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
ARG FUNCTION_DIR
RUN apt-get update && apt-get install gnupg wget -y && \
    wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
    sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \
    apt-get update && \
    apt-get install google-chrome-stable -y --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir -p ${FUNCTION_DIR}/
COPY . ${FUNCTION_DIR}
RUN ls ${FUNCTION_DIR}
WORKDIR ${FUNCTION_DIR}
RUN npm install

FROM public.ecr.aws/lambda/nodejs:latest
ARG FUNCTION_DIR
WORKDIR ${FUNCTION_DIR}
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
RUN ls ${FUNCTION_DIR}
COPY package.json ${FUNCTION_DIR}
RUN npm install
COPY . ${FUNCTION_DIR}

RUN npm run build
RUN ls ${FUNCTION_DIR}/node_modules
RUN node node_modules/puppeteer/install.js
CMD [ "/function/dist/api/generate.pdf" ]

但收到此错误: "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"

一个工作示例...

Dockerfile

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

ENV PATH /opt/node_app/node_modules/.bin:$PATH
ENV NODE_ENV production
ENV AWS_NODEJS_CONNECTION_REUSE_ENABLED 1
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

RUN yum install wget curl -y
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
RUN yum install ./google-chrome-stable_current_*.rpm -y

COPY package.json ${LAMBDA_TASK_ROOT}
COPY server.js ${LAMBDA_TASK_ROOT}

RUN npm install
RUN npm cache clean --force

CMD [ "server.main" ]

木偶配置

const options = {
    executablePath: '/usr/bin/google-chrome',
    args: [
        '--disable-extensions',
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-gpu'
    ]
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM