From 2f8b7a6440af4b2aca0d8066192ee25288bdb62d Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 4 May 2022 13:37:18 +0000 Subject: [PATCH] chore: add Dockerfile This PR adds an official Dockerfile for Puppeteer along with basic testsing for the images built using the Dockerfile. Licenses from the Chromium binary are put into THIRD_PARTY_NOTICED txt file. --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++++++++ docker/Dockerfile | 31 +++++++++++++++++++++++++++++++ docker/README.md | 19 +++++++++++++++++++ docker/pack.sh | 13 +++++++++++++ docker/test/smoke-test.js | 9 +++++++++ 5 files changed, 104 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/README.md create mode 100755 docker/pack.sh create mode 100644 docker/test/smoke-test.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74b508eed1070..09e52efc060f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -181,3 +181,35 @@ jobs: run: | # Note: this modifies package.json to test puppeteer-core, so we test this last. npm run test:install + + docker-tests: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + node: [16] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Set up Node.js + uses: actions/setup-node@v3.1.1 + with: + node-version: ${{ matrix.node }} + - name: Install dependencies + run: | + npm install + ls .local-chromium + - name: Build + run: | + npm run build + docker/pack.sh + - name: Build docker image + working-directory: ./docker + run: | + docker build -t puppeteer-test-image . + - name: Run smoke test + working-directory: ./docker + run: | + docker run -i --init --cap-add=SYS_ADMIN --rm puppeteer-test-image node -e "`cat test/smoke-test.js`" diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000000000..1d7884cd8035d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,31 @@ +FROM node:16 + +# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others) +# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer +# installs, work. +RUN apt-get update \ + && apt-get install -y wget gnupg \ + && 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 libxss1 \ + --no-install-recommends \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /home/pptruser + +COPY puppeteer-latest.tgz /home/pptruser/puppeteer-latest.tgz + +# Install puppeteer into /home/pptruser/node_modules. +RUN npm i ./puppeteer-latest.tgz \ + && rm puppeteer-latest.tgz \ + # Add user so we don't need --no-sandbox. + # same layer as npm install to keep re-chowned files from using up several hundred MBs more space + && groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \ + && mkdir -p /home/pptruser/Downloads \ + && chown -R pptruser:pptruser /home/pptruser \ + && (node -e "require('child_process').execSync(require('puppeteer').executablePath() + ' --credits', {stdio: 'inherit'})" > THIRD_PARTY_NOTICES) + +USER pptruser + +CMD ["google-chrome-stable"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000000000..d743e7edc9aa9 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,19 @@ +# Dockerfile for Puppeteer + +This directory contains files needed to containerize Puppeteer. The major problem +that this is solving is the problem of providing all dependencies required to run a +browser instance. + +## Building the image + +```sh +docker build -t puppeteer-chrome-linux . # `puppeteer-chrome-linux` is the name of the image. +``` + +## Running the image + +```sh +docker run -i --init --rm --cap-add=SYS_ADMIN --name puppeteer-chrome puppeteer-chrome-linux node -e "`cat test.js`" +``` + +`--cap-add=SYS_ADMIN` capability is needed to enable Chromium sandbox that makes the browser more secure. Alternatively, it should be possible to start the browser binary with the `--no-sandbox` flag. diff --git a/docker/pack.sh b/docker/pack.sh new file mode 100755 index 0000000000000..3a67868d2a8d8 --- /dev/null +++ b/docker/pack.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Packs puppeteer using npm and moves the archive file to docker/puppeteer-latest.tgz. +# Expected cwd: project root directory. + +set -e +set +x + +FILENAME=$(npm pack) + +echo $FILENAME + +mv $FILENAME docker/puppeteer-latest.tgz diff --git a/docker/test/smoke-test.js b/docker/test/smoke-test.js new file mode 100644 index 0000000000000..d170ff39d2a02 --- /dev/null +++ b/docker/test/smoke-test.js @@ -0,0 +1,9 @@ +const puppeteer = require('puppeteer'); + +(async () => { + const browser = await puppeteer.launch(); + const page = await browser.newPage(); + await page.goto('https://example.com'); + await browser.close(); + console.log('done'); +})();