devops: bake browsers into Docker image (#2990)

This patch bakes browsers into docker image.

Important observations:
- We now re-build docker image everytime we roll browsers.
- Docker image size almost doubles: from `225MB` to `496MB`.

References #2926
This commit is contained in:
Andrey Lushnikov 2020-07-17 16:51:39 -07:00 committed by GitHub
parent 9a2245d30a
commit 7d2078ef6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 25 deletions

View file

@ -7,6 +7,7 @@ on:
- release-*
paths:
- docs/docker/**
- browsers.json
jobs:
publish-canary-docker:
@ -14,6 +15,12 @@ jobs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 10.15
- run: npm ci
- run: npm run build
- run: ./docs/docker/build.sh --prepare-context
- uses: docker/build-push-action@v1
with:
username: playwright

View file

@ -29,6 +29,12 @@ jobs:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 10.15
- run: npm ci
- run: npm run build
- run: ./docs/docker/build.sh --prepare-context
- uses: docker/build-push-action@v1
with:
username: playwright

View file

@ -1,2 +1,2 @@
(generated with docker-image-size.sh)
225M
496M

View file

@ -1,12 +1,3 @@
################################################
# Compile with:
# sudo docker build -t microsoft/playwright:bionic -f Dockerfile.bionic .
#
# Run with:
# sudo docker run -d -p --rm --name playwright microsoft/playwright:bionic
#
#################################################
FROM ubuntu:bionic
# 1. Install node12
@ -72,3 +63,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# 9. Run everything after as non-privileged user.
USER pwuser
# === BAKE BROWSERS INTO IMAGE ===
# 1. Add tip-of-tree Playwright package to install its browsers.
# The package should be built beforehand from tip-of-tree Playwright.
COPY --chown=pwuser ./playwright.tar.gz /home/pwuser/playwright.tar.gz
# 2. Install playwright and then delete the installation.
# Browsers will remain downloaded in `/home/pwuser/.cache/ms-playwright`.
RUN mkdir /home/pwuser/tmp && cd /home/pwuser/tmp && npm init -y && \
npm i ../playwright.tar.gz && \
cd ../ && rm -rf tmp && rm /home/pwuser/playwright.tar.gz

View file

@ -2,7 +2,7 @@
[Dockerfile.bionic](Dockerfile.bionic) is a playwright-ready image of playwright.
This image includes all the dependencies needed to run browsers in a Docker
container.
container, including browsers.
<!-- GEN:toc -->
- [Usage](#usage)
@ -47,17 +47,29 @@ See our [Continuous Integration guides](../ci.md) for sample configs.
### Build the image
Use [`//docs/docker/build.sh`](build.sh) to build the image.
```
$ docker build -t mcr.microsoft.com/playwright:bionic -f Dockerfile.bionic .
$ ./docs/docker/build.sh
```
The image will be tagged as `playwright:localbuild` and could be run as:
```
$ docker run --rm -it playwright:localbuild /bin/bash
```
> **NOTE**: any commit that changes docker image should also update [`//docs/docker/CURRENT_DOCKER_IMAGE_SIZE`](CURRENT_DOCKER_IMAGE_SIZE). Please run [`//docs/docker/docker-image-size.sh`](docker-image-size.sh) locally and commit updated number.
### Push
Playwright on Docker Hub is published via the [Microsoft Container Registry](https://github.com/microsoft/containerregistry).
Docker images are published automatically by Github Actions. We currently publish the following
images:
- `mcr.microsoft.com/playwright:dev` - tip-of-tree image version.
- `mcr.microsoft.com/playwright:bionic` - last Playwright release docker image.
- `mcr.microsoft.com/playwright:sha-XXXXXXX` - docker image for every commit that changed
docker files or browsers, marked with a [short sha](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Short-SHA-1) (first 7 digits of the SHA commit).
```
$ docker push playwright.azurecr.io/public/playwright:bionic
```
## Base images

44
docs/docker/build.sh Executable file
View file

@ -0,0 +1,44 @@
#!/bin/bash
set -e
set +x
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
echo "usage: $(basename $0) [--prepare-only]"
echo
echo "Build Playwright docker image and tag it as 'playwright:localbuild'."
echo "Once image is built, you can run it with"
echo ""
echo " docker run --rm -it playwright:localbuild /bin/bash"
echo ""
echo "NOTE: this requires on Playwright dependencies to be installed with 'npm install'"
echo " and Playwright itself being built with 'npm run build'"
echo
echo " --prepare-context prepare docker context and skip building."
echo " This is to defer building & publishing to Docker Github Action."
echo ""
exit 0
fi
PREPARE_CONTEXT_ONLY=""
if [[ $1 == "--prepare-context" ]]; then
PREPARE_CONTEXT_ONLY="1"
fi
function cleanup() {
if [[ -z "${PREPARE_CONTEXT_ONLY}" ]]; then
rm -f "playwright.tar.gz"
fi
}
trap "cleanup; cd $(pwd -P)" EXIT
cd "$(dirname "$0")"
# We rely on `./playwright.tar.gz` to download browsers into the docker
# image.
node ../../packages/build_package.js playwright ./playwright.tar.gz
if [[ -n "${PREPARE_CONTEXT_ONLY}" ]]; then
exit 0
fi
docker build -t "playwright:localbuild" -f Dockerfile.bionic .

View file

@ -5,25 +5,49 @@ set +x
# This script computes **compressed image size with all its layers**.
# This solution is based on https://stackoverflow.com/a/55156181/314883
DOCKER_IMAGE_NAME="docker-image-to-count-compressed-size"
if [[ ($1 == '--help') || ($1 == '-h') ]]; then
echo "usage: $(basename $0) [--image-name <local image to compute size>]"
echo
echo "Compute docker image size defined by the 'Dockerfile.bionic'."
echo ""
echo "Script will build the image using 'build.sh', unless '--image-name'"
echo "is specified."
echo ""
echo "NOTE: this requires on Playwright dependencies to be installed with 'npm install'"
echo " and Playwright itself being built with 'npm run build'"
echo
echo " --image-name custom image name to compute size of."
echo ""
exit 0
fi
CUSTOM_IMAGE_NAME=""
if [[ $1 == "--image-name" ]]; then
CUSTOM_IMAGE_NAME=$2
fi
TMP_IMAGE_NAME="docker-image-to-count-compressed-size"
FILE_NAME="docker-image-to-count-compressed-size"
function cleanup() {
echo "-- Removing .tar if any"
rm -f "${FILE_NAME}.tar"
echo "-- Removing .tar.gz if any"
rm -f "${FILE_NAME}.tar.gz"
echo "-- Removing docker image if any"
docker rmi "${DOCKER_IMAGE_NAME}:bionic" >/dev/null
docker rmi "${TMP_IMAGE_NAME}:bionic" >/dev/null
}
trap "cleanup; cd $(pwd -P)" EXIT
cd "$(dirname "$0")"
echo "-- Building image..."
docker build -t "${DOCKER_IMAGE_NAME}:bionic" -f Dockerfile.bionic . >/dev/null
echo "-- Saving .tar of the image..."
docker save "${DOCKER_IMAGE_NAME}:bionic" > "${FILE_NAME}.tar"
if [[ -z "${CUSTOM_IMAGE_NAME}" ]]; then
echo "-- Building image..."
./build.sh >/dev/null
echo "-- Saving .tar of the image..."
docker save "${TMP_IMAGE_NAME}:bionic" > "${FILE_NAME}.tar"
else
echo "-- Saving .tar of the image..."
docker save "${CUSTOM_IMAGE_NAME}" > "${FILE_NAME}.tar"
fi
echo "-- Compressing image..."
gzip "${FILE_NAME}.tar" >/dev/null