SamuelScheit / puppeteer-stream

A Library for puppeteer to retrieve audio and video streams of webpages
MIT License
363 stars 116 forks source link

[Bug] Not working in docker #8

Open akhil-kp-dasan opened 3 years ago

akhil-kp-dasan commented 3 years ago

I was trying to use this library inside a docker container using Xvfb tool. But I came across this issue where the getStream function only doesn't work reliably. Every now and then it throws this error:

(node:33) UnhandledPromiseRejectionWarning: Error: Evaluation failed: TypeError: Cannot read property 'capture' of undefined
    at START_RECORDING (chrome-extension://jjndjgheafjngoipoacpjgeicjeomjli/background.js:27:32)
    at __puppeteer_evaluation_script__:4:13
    at ExecutionContext._evaluateInternal (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:218:19)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async ExecutionContext.evaluate (/app/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:107:16)
(node:33) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:33) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

It look like on some runs the chrome object has only keys available [ 'loadTimes', 'csi' ] other times all the APIs are present. Not sure what would make rest of the keys unavailable randomly.

Please let me know if there is any other information I need to provide to help debug this issue.

SamuelScheit commented 3 years ago

Ok thank you for your bug report I’ll have a look

SamuelScheit commented 3 years ago

It seems like I can't reproduce the issue, apparently chrome in docker can't capture tabs?

Aliaksandr-Kasko-JazzTeam commented 3 years ago

Use this dockerfile

FROM node:14.16.0-buster-slim

RUN apt-get update \
    && apt-get install -y gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 \
       libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
       libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation \
       libappindicator1 libnss3 lsb-release xdg-utils wget x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic \
       x11-apps gnupg procps ffmpeg xvfb \
    && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && 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 -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf \
      --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

#Do something you want here

RUN yarn install
#Create virtual screen with custom resolution and run your app
CMD xvfb-run --server-args="-screen 0 1920x1080x24" node "index.js"

Also send --no-sandbox options to launch function:

const browser = await launch({
  defaultViewport: {
    width: 1920,
    height: 1080
  },
  args: ['--no-sandbox']
});
ArslanMehmoodTkxel commented 2 years ago

so this library is not working in docker at all or there is some specific scenario for this? Also can someone send the working docker file.

nivhsay commented 1 year ago

I am using the latest version of this library in docker without issues (except super high CPU from chrome processes - which I am still trying to resolve).

Maybe you're launching chromium instead of chrome?

I have to explicitly use google-chrome in the launch options.

await launch({ 
    executablePath: 'google-chrome', 
    //... your other options
});

Since you don't need chromium, you can set ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in your Dockerfile so that it's not installed when installing puppeteer.

It should not matter,but for some reason,chromium didn't work in my case. Chrome did.

shokymk commented 1 year ago

I am using the latest version of this library in docker without issues (except super high CPU from chrome processes - which I am still trying to resolve).

Maybe you're launching chromium instead of chrome?

I have to explicitly use google-chrome in the launch options.

await launch({ 
    executablePath: 'google-chrome', 
    //... your other options
});

Since you don't need chromium, you can set ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in your Dockerfile so that it's not installed when installing puppeteer.

It should not matter,but for some reason,chromium didn't work in my case. Chrome did.

Hey @nivhsay . Would you be able to give an example of how your Dockerfile looks like?

yashkhandelwal05 commented 1 year ago

Hi @nivhsay Have you been able to identify how to reduce the CPU usage?

nivhsay commented 1 year ago

I am using the latest version of this library in docker without issues (except super high CPU from chrome processes - which I am still trying to resolve). Maybe you're launching chromium instead of chrome? I have to explicitly use google-chrome in the launch options.

await launch({ 
    executablePath: 'google-chrome', 
    //... your other options
});

Since you don't need chromium, you can set ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in your Dockerfile so that it's not installed when installing puppeteer. It should not matter,but for some reason,chromium didn't work in my case. Chrome did.

Hey @nivhsay . Would you be able to give an example of how your Dockerfile looks like?

@shokymk, nothing special in the Dockerfile. I had to omit proprietary things from it but nothing that should affect the use of this package.

FROM node:18.16-buster

RUN apt-get update \
    && apt-get install -y xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 \
       libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \
       libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation \
       libappindicator1 libnss3 lsb-release xdg-utils x11vnc x11-xkb-utils xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic \
       x11-apps gnupg procps libpcre3 libpcre3-dev zlib1g-dev \
       fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf fonts-noto-color-emoji \
       libgbm1 libu2f-udev libvulkan1 libxss1 --no-install-recommends

COPY ./google-chrome/stable-114.deb /tmp/google-chrome.deb
RUN dpkg -i /tmp/google-chrome.deb
RUN rm /tmp/google-chrome.deb

RUN rm -rf /var/lib/apt/lists/*

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

ENTRYPOINT ["yarn", "start:prod"]
nivhsay commented 1 year ago

Hi @nivhsay Have you been able to identify how to reduce the CPU usage?

@yashkhandelwal05, probably the usage of GPUs with the container. Without GPU, all recording/transcoding is done on the CPU. Did not try it yet.

priya141 commented 1 year ago

It looks like you're encountering an "UnhandledPromiseRejectionWarning" in a Node.js application that uses Puppeteer, a library for controlling headless Chrome or Chromium browsers. The warning message indicates that a promise was rejected but not properly handled.

The specific error message you provided, "TypeError: Cannot read property 'capture' of undefined," suggests that there's an issue with the code trying to access the 'capture' property of an undefined object.

Here's what you can do to address this issue:

Check Your Code: Look at the line number mentioned in the error message (line 27 of background.js in the extension). Check if you are trying to access the 'capture' property of an object that might be undefined. Make sure that you're initializing and using the object correctly.

Error Handling: Wrap the problematic part of your code in a try-catch block to handle any errors that might occur during the promise execution. This will prevent unhandled promise rejections and help you capture and handle errors gracefully.

try { // Your code that might be causing the error } catch (error) { console.error("An error occurred:", error); } Promise Rejection Handling: If you're using asynchronous operations that return promises (like Puppeteer functions), make sure you're using await with them and handling promise rejections with try-catch or .catch() to avoid unhandled promise rejections.

try { const result = await someAsyncFunction(); // Handle the result } catch (error) { console.error("An error occurred:", error); } Deprecation Warning: The warning message also mentions that unhandled promise rejections are deprecated, and they could terminate the Node.js process in the future. To prevent this, make sure you handle all promise rejections properly using the methods mentioned above.

Update Dependencies: Sometimes, these issues could be due to bugs in older versions of libraries. Make sure you're using the latest versions of Puppeteer and other relevant dependencies.

If you're still facing issues after trying these steps, it might help to provide more context or code snippets related to the error so that I can offer more specific assistance.

sniirful commented 9 months ago

I'm not sure if this is still an issue here, but to me it worked flawlessly. Here is my Dockerfile:

FROM node:20.11.0

RUN apt update && apt install -y chromium xvfb
RUN npm i -g typescript

WORKDIR /app
# we first copy the package.json file, so if that doesn't change
# there's no need to run "npm i" every single time we build
# the container
COPY package.json .
COPY package-lock.json .
RUN npm i
# eventually, everything else
COPY . .
RUN tsc

CMD xvfb-run --server-args="-screen 0 1024x768x24" node src

And here the code to make it work:

import puppeteer from 'puppeteer';
import { launch as launchBrowser, getStream as getPuppeteerStream } from 'puppeteer-stream';
import { Browser, Page } from 'puppeteer-stream/node_modules/puppeteer-core';

// ...

// initialize the browser
let browser: Browser;
(async () => {
    browser = await launchBrowser({
        defaultViewport: {
            width: 1920,
            height: 1080,
        },
        headless: false,
        executablePath: puppeteer.executablePath(),
        args: ['--no-sandbox'],
    });
})();

// ...
fernandomarca commented 2 weeks ago

docker file

FROM  node:20-slim

RUN apt-get update && \
  apt-get install -y \
  wget \
  unzip \
  xvfb \
  libxi6 \
  libgconf-2-4 \
  gnupg \
  curl \
  && rm -rf /var/lib/apt/lists/*

RUN curl -fSsL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | tee /usr/share/keyrings/google-chrome.gpg > /dev/null

RUN echo deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main | tee /etc/apt/sources.list.d/google-chrome.list

RUN apt-get update && apt-get install -y google-chrome-stable

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

EXPOSE 3334

CMD ["npm", "start"]

docker compose

version: '3.8'

services:
  fastify-app:
    build: .
    ports:
      - "3334:3334"
    volumes:
      - .:/app
      - /app/node_modules
      - /tmp/.X11-unix:/tmp/.X11-unix
    environment:
      NODE_ENV: development
      DISPLAY: ${DISPLAY}
sniirful commented 2 weeks ago

You maybe want to run it using xvfb-run like I did?