puppeteer icon indicating copy to clipboard operation
puppeteer copied to clipboard

The chromium binary is not available for arm64

Open cdeutsch opened this issue 2 years ago • 58 comments

Bug description

In an ARM based Docker container (or ARM based Linux):

  1. npm install puppeteer

Error:

The chromium binary is not available for arm64.

This is related to #6622 which wasn't really solved just worked around via Rosetta.

I'm trying to build an ARM based Docker Image that uses BackstopJS/puppeteer. Ref https://github.com/garris/BackstopJS/issues/1300

Are there any plans to build an arm64 version of chromium?

Puppeteer version

10.0.0

Node.js version

16.3.0

npm version

7.15.1

What operating system are you seeing the problem on?

Linux

Relevant log output

No response

cdeutsch avatar Nov 03 '21 00:11 cdeutsch

I have arm64 Chromium binaries available at www.chromiumforlambda.com

lifesaverluke avatar Nov 05 '21 07:11 lifesaverluke

A workaround I'm using is to install chromium with the base image's package manager (e.g. apk add chromium if you're using the node alpine image), and then use ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in the Dockerfile before npm install puppeteer to tell puppeteer to skip installing chromium. You may have to change the puppeteer executable path to use the package manager's version of chromium.

talisto avatar Nov 16 '21 17:11 talisto

Thanks @talisto, that's what I've been doing as a work around, but took two days to come up with that. https://github.com/garris/BackstopJS/issues/1300#issuecomment-958561525

I'm using puppeteer via Backstop JS and in my scenario Backstop uses a Docker image to do the screenshot comparisons (yields consistent results across OSes)

It would be nice if npm install puppeteer worked for multi-platform Docker images instead of trying to figure out how to add chromium yourself.

cdeutsch avatar Nov 16 '21 19:11 cdeutsch

It would be nice if npm install puppeteer worked for multi-platform Docker images instead of trying to figure out how to add chromium yourself.

This ^

ljupcospeci avatar Dec 07 '21 10:12 ljupcospeci

A workaround I'm using is to install chromium with the base image's package manager (e.g. apk add chromium if you're using the node alpine image), and then use ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in the Dockerfile before npm install puppeteer to tell puppeteer to skip installing chromium. You may have to change the puppeteer executable path to use the package manager's version of chromium.

hello, could you please share your dockerfile, thank you!

cjbd avatar Jan 19 '22 05:01 cjbd

Another workaround is to use a custom browser with something like:

const browserPromise = puppeteer.launch({
    args: ['--disable-gpu', '--disable-setuid-sandbox', '--no-sandbox', '--ignore-certificate-errors', '--disable-web-security', '--disable-features=IsolateOrigins', '--disable-site-isolation-trials'],
    defaultViewport: {
      width: measures.width,
      height: measures.height
    }
  });
penthouse({
    url: url,
    css: path.join(__basedir + sourceCss),
    width: measures.width,
    height: measures.height,
    timeout: 30000,
    maxEmbeddedBase64Length: 1000,
    userAgent: userAgent,
    renderWaitTime: 4000,
    blockJSRequests: true,
    keepLargerMediaQueries: true,
    pageLoadSkipTimeout: 7000,
    puppeteer: {
      getBrowser: () => browserPromise
    }
  })

Obviously, choose a user agent you need and tweak the custom browser options.

csaltos avatar Jan 25 '22 18:01 csaltos

A workaround I'm using is to install chromium with the base image's package manager (e.g. apk add chromium if you're using the node alpine image), and then use ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true in the Dockerfile before npm install puppeteer to tell puppeteer to skip installing chromium. You may have to change the puppeteer executable path to use the package manager's version of chromium.

@talisto would you mind sharing your Dockerfile to help all of this issue's followers?

davidbielik avatar Mar 28 '22 15:03 davidbielik

@talisto would you mind sharing your Dockerfile to help all of this issue's followers?

This is what I'm currently using:

FROM node:16-alpine3.15

RUN apk add --no-cache \
    msttcorefonts-installer font-noto fontconfig \
    freetype ttf-dejavu ttf-droid ttf-freefont ttf-liberation \
    chromium \
  && rm -rf /var/cache/apk/* /tmp/*

RUN update-ms-fonts \
    && fc-cache -f

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

WORKDIR /app

RUN npm init -y &&  \
    npm i puppeteer express

RUN addgroup pptruser \
    && adduser pptruser -D -G pptruser \
    && mkdir -p /home/pptruser/Downloads \
    && chown -R pptruser:pptruser /home/pptruser \
    && chown -R pptruser:pptruser /app

USER pptruser

COPY src/server.js /app

EXPOSE 8080

CMD ["yarn", "start"]

..some of which I lifted from here: https://github.com/ebidel/try-puppeteer/blob/master/backend/Dockerfile

..which is mostly based on the "Running Puppeteer in Docker" section of the Puppeteer troubleshooting docs: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker

The only relevant bits to this issue are the ENV statements, and adding chromium to the packages installed by the package manager.

talisto avatar Mar 28 '22 22:03 talisto

I just noticed that the Puppeteer docs actually have an example for Docker using Alpine which also sets PUPPETEER_SKIP_CHROMIUM_DOWNLOAD and uses the package manager to download Chromium:

https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-on-alpine

talisto avatar Mar 28 '22 23:03 talisto

It's important to note the tight version requirements between Puppeteer and Chromium when using this approach. The version of Chromium currently available in alpine3.15 is 99.0.4844.84-r0, which mean the versions of Puppeteer you could/should use are 13.2.0-13.4.1. However, if you're using an alpine3.14 image, you'll get Chromium 93.0.4577.82-r0, which maps to Puppeteer 10.2.0-11.0.0.

ngraef avatar Mar 28 '22 23:03 ngraef

My image bases on debian, so I have to apt install chromium and include the env variables. Are there any chances these binaries for arm64 will become available?

flaushi avatar May 04 '22 09:05 flaushi

It's important to note the tight version requirements between Puppeteer and Chromium when using this approach. The version of Chromium currently available in alpine3.15 is 99.0.4844.84-r0, which mean the versions of Puppeteer you could/should use are 13.2.0-13.4.1. However, if you're using an alpine3.14 image, you'll get Chromium 93.0.4577.82-r0, which maps to Puppeteer 10.2.0-11.0.0.

How do you get the mapping from Chromium 99.0.4844.84-r0 to puppeteer versions 13.2.0-13.4.1? Inspecting revisions.ts for 13.4.0, I see here https://github.com/puppeteer/puppeteer/blob/v13.4.0/src/revisions.ts

export const PUPPETEER_REVISIONS: Revisions = {
  chromium: '961656',
  firefox: 'latest',
};

I am trying to solve this for debian bullseye, which would install https://packages.debian.org/de/bullseye/chromium version 99.0.4844.74-1~deb11u1. Seems it's the same version rquirements but I don't get the mapping from 961656 to version 99.0.4844.84-r0 ...

flaushi avatar May 05 '22 08:05 flaushi

That's pretty annoying. Thanks for sharing @flaushi looks like I have to go to the same rabbit hole like you. I'm not sure about how to map the versions together. From the current docs it says:

The newest Chromium package supported on Alpine is 100, which corresponds to Puppeteer v13.5.0.

But the revisions.ts of v13.5.0 claims: https://github.com/puppeteer/puppeteer/blob/7b38b458c91f4180a29cee10698a909bea911f67/src/revisions.ts#L22-L25

confusing

nook24 avatar May 06 '22 11:05 nook24

How do you get the mapping from Chromium 99.0.4844.84-r0 to puppeteer versions 13.2.0-13.4.1?

I check the CHANGELOG, which is also published as GitHub release notes. Puppeteer releases that pull in a new Chromium version will include the version and snapshot revision number. For example:

13.2.0 (2022-02-07)

Features

  • chromium: roll to Chromium 99.0.4844.16 (r961656)

That version applies until the next release that notes a Chromium change.

ngraef avatar May 06 '22 15:05 ngraef

Does anyone have a viable workaround for running Puppeteer 13 or 14 via Docker on an M1 mac using a Debian Node base image? e.g.

docker buildx build --push --platform linux/amd64,linux/arm64 ...

FROM node:16.15.1-bullseye-slim

RUN apt-get update && apt-get install --no-install-recommends -yq dumb-init \
  # Install Chromium dependencies, necessary for running Puppeteer
  # Consult the Debian dependencies list for an updates when bumping Puppeteer or base images:
  # https://developers.google.com/web/tools/puppeteer/troubleshooting#chrome_headless_doesnt_launch_on_unix
  ca-certificates fonts-liberation libayatana-appindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 \
  libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 \
  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 lsb-release wget xdg-utils \
  && apt-get clean && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*

RUN yarn global add [email protected]

Happy for rosetta emulation at this point since a native arm64 binary doesn't exist yet, but so far my attempts at running an amd64 version on an M1 result in qemu crashing when attempting to launch puppeteer.

ReDrUm avatar Jun 22 '22 06:06 ReDrUm

@ReDrUm you can test my Dockerfile: https://github.com/it-novum/puppeteer-docker/blob/development/Dockerfile I have not tested it on Apple M1, but it is running on Linux arm64.

nook24 avatar Jun 22 '22 07:06 nook24

@ReDrUm the ideal fix would be an arm build of Chromium for Debian, but doesn't sound like that's on Puppeteer's radar.

Here's the Dockerfile I used to work around my issues (unfortunately it's an old version of Chrome) https://github.com/garris/BackstopJS/issues/1300#issuecomment-1018707468

cdeutsch avatar Jun 22 '22 18:06 cdeutsch

I've spent a few hours trying to run one of our Docker containers on Linux/arm64, it was hard and mostly trial and error mode. My final setup is Debian 11 and Chromium 103.0.5060.53 built on Debian 11.3, running on Debian 11.3, the magic is in the bunch of flags I have had to set to make Puppeteer not stuck on a await browser.newPage(), and avoid segment faults and device access errors.

FROM node:16-bullseye-slim

ENV DEBIAN_FRONTEND noninteractive
RUN apt update -qq \
    && apt install -qq -y --no-install-recommends \
      curl \
      git \
      gnupg \
      libgconf-2-4 \
      libxss1 \
      libxtst6 \
      python \
      g++ \
      build-essential \
      chromium \
      chromium-sandbox \
      dumb-init \
      fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst \
    && rm -rf /var/lib/apt/lists/* \
    && rm -rf /src/*.deb

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV CHROME_PATH=/usr/bin/chromium
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium

WORKDIR /home/pptruser

# Add user to not run as a root.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
      && mkdir -p /home/pptruser/Downloads \
      && chown -R pptruser:pptruser /home/pptruser

COPY package*.json /home/pptruser/
COPY tasks.js /home/pptruser/
COPY processes.config.js /home/pptruser/
RUN chown -R pptruser:pptruser /home/pptruser;

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

# the install is retry threee times with a pause of 10 seconds
RUN for i in 1 2 3; \
    do \
      npm install --no-optional;\
      sleep 10; \
      ([ $i -eq 3 ] && exit 1) || true; \
    done;

ENTRYPOINT ["dumb-init", "--"]
CMD ["node_modules/.bin/pm2-docker", "processes.config.js"]
  const browser = await puppeteer.launch({
    pipe: true,
    headless: true,
    dumpio: true,
    args: [
      '--disable-dev-shm-usage',
      '--disable-setuid-sandbox',
      '--no-sandbox',
      '--no-zygote',
      '--disable-gpu',
      '--disable-audio-output',
      '--headless',
      '--single-process'
    ] 
  })
  const page = await browser.newPage()

the whole PR is at https://github.com/elastic/apm-integration-testing/pull/1493

kuisathaverat avatar Jun 23 '22 18:06 kuisathaverat

Thanks! I now have a working copy by installing chromium=103.0.5060.53-1~deb11u1 and mapping it to [email protected]. I tried going to puppeteer@^15 but there were some problems with the TypeScript types between 15.0.015.1.1, and 15.1.0 upgraded to Chromium 104 which blocked me going to 15.x since Debian is still stuck on Chromium 103 for now.

Fingers crossed we get some arm64 binaries direct from puppeteer in the near future to avoid having to wait for Debian stable 🤞

ReDrUm avatar Jun 29 '22 06:06 ReDrUm

Is anyone else running multi-arch images for visual-regression testing and noticing discrepancies between visual snapshots taken on say an amd64 vs arm64 image? For my codebase i'm seeing differences in drop shadows between systems using the same Debian image (albeit it the chromium arch differs)

ReDrUm avatar Jul 01 '22 04:07 ReDrUm

@ReDrUm you can test my Dockerfile: it-novum/puppeteer-docker@development/Dockerfile I have not tested it on Apple M1, but it is running on Linux arm64.

M1 Pro (MacOS 12.2.1 ) is working fine!

zenghongtu avatar Jul 05 '22 15:07 zenghongtu

Is anyone else running multi-arch images for visual-regression testing and noticing discrepancies between visual snapshots taken on say an amd64 vs arm64 image? For my codebase i'm seeing differences in drop shadows between systems using the same Debian image (albeit it the chromium arch differs)

@ReDrUm This is just HELL. Been trying to solve this issue of supporting both AMD and ARM environments for over a month now, tried so manny approaches and nothing holds so far.

Have you find a working and stable solution?

sag1v avatar Jul 27 '22 14:07 sag1v

All I had to do to get it working on my M1 chip was add:

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium

 RUN apt-get install -y chromium  \
    && apt-get clean

Then added executablePath: '/usr/bin/chromium', when launching puppeteer:

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

kleky avatar Aug 12 '22 21:08 kleky

We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

stale[bot] avatar Oct 11 '22 22:10 stale[bot]

It'd be great to address this because chromium is so painful to build oneself. Packaging arm binaries within puppeteer like other arches would be greatly beneficial since it would help guarantee puppeteer / chromium compatibility.

freewil avatar Oct 11 '22 22:10 freewil

The ARM binary is available with the env var PUPPETEER_EXPERIMENTAL_CHROMIUM_MAC_ARM. We are going to fully support it once GitHub Actions offer Mac ARM devices.

P.S. the env var downloads the build for Mac ARM though but afaik there are not chromium builds published for Linux ARM. P.P.S. https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html

OrKoN avatar Oct 12 '22 12:10 OrKoN

the env var downloads the build for Mac ARM though but afaik there are not chromium builds published for Linux ARM.

If you run Puppeteer on Apple Silicon in Docker, you need the Linux ARM version.

Would love to see it added.

cdeutsch avatar Oct 12 '22 13:10 cdeutsch

Also, Linux ARM is becoming more common with public clouds (thinking mainly AWS Graviton here in my experience).

freewil avatar Oct 12 '22 16:10 freewil

https://linguinecode.com/post/how-to-fix-m1-mac-puppeteer-chromium-arm64-bug this helped me

AzharUddinSheikh avatar Nov 15 '22 15:11 AzharUddinSheikh

https://linguinecode.com/post/how-to-fix-m1-mac-puppeteer-chromium-arm64-bug this helped me

Step 2: Allow Chromium to open on your M1 Mac:

Use the following command instead

 xattr -cr /Applications/Chromium.app

yoyo837 avatar Nov 15 '22 16:11 yoyo837