puppeteer
puppeteer copied to clipboard
The chromium binary is not available for arm64
Bug description
In an ARM based Docker container (or ARM based Linux):
-
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
I have arm64 Chromium binaries available at www.chromiumforlambda.com
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.
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.
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 ^
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 useENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
in the Dockerfile beforenpm 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!
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.
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 useENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
in the Dockerfile beforenpm 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?
@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.
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
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.
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?
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 ...
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
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.
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 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.
@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
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
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.0
→ 15.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 🤞
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 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!
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?
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'
] });
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.
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.
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
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.
Also, Linux ARM is becoming more common with public clouds (thinking mainly AWS Graviton here in my experience).
https://linguinecode.com/post/how-to-fix-m1-mac-puppeteer-chromium-arm64-bug this helped me
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