The headless-shell project provides a multi-arch container
image, docker.io/chromedp/headless-shell, containing
Chrome's headless-shell -- a slimmed down version of Chrome that is useful
for driving, profiling, or testing web pages.
This image has been created for the Go chromedp package, which
provides a simple and easy to use API for driving browsers compatible with the
Chrome Debugging Protocol, but can be used with library or
application that supports the Chrome Debugging Protocol.
The version of headless-shell contained in the docker.io/chromedp/headless-shell
has been modified from the original Chromium source tree, to report the same
user agent as Chrome, and has had other minor modifications made to it in order
to make it better suited for use in an embedded context.
Multi-arch images for Chrome's stable, beta, and dev channels are pushed
daily to the docker.io/chromedp/headless-shell
repository.
The image can be used via the stable, beta, or dev floating tags, or via
a specific version tag:
# pull latest stable
$ podman pull docker.io/chromedp/headless-shell:latest
# pull specific version
$ podman pull docker.io/chromedp/headless-shell:123.0.6312.86
# pull beta
$ podman pull docker.io/chromedp/headless-shell:beta
# pull dev
$ podman pull docker.io/chromedp/headless-shell:devThe headless-shell container can be used in the usual way:
# run
$ podman run -d -p 9222:9222 --rm --name headless-shell docker.io/chromedp/headless-shell
# if headless-shell is crashing with a BUS_ADRERR error, pass a larger shm-size:
$ podman run -d -p 9222:9222 --rm --name headless-shell --shm-size 2G docker.io/chromedp/headless-shell
# run as unprivileged user
# get seccomp profile from https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json
$ podman run -d -p 9222:9222 --user nobody --security-opt seccomp=chrome.json --entrypoint '/headless-shell/headless-shell' docker.io/chromedp/headless-shell --remote-debugging-address=0.0.0.0 --remote-debugging-port=9222 --disable-gpu --enable-unsafe-swiftshader --headlessWhen using docker.io/chromedp/headless-shell (either directly or as a base
image), you could experience zombie processes problem. To reap zombie
processes, use podman run's --init arg:
$ podman run -d -p <PORT>:<PORT> --name <your-program> --init <your-image>If running Docker older than 1.13.0, use dumb-init or
tini on your Dockerfile's ENTRYPOINT
FROM docker.io/chromedp/headless-shell:latest
...
# Install dumb-init or tini
RUN apt install dumb-init
# or RUN apt install tini
...
ENTRYPOINT ["dumb-init", "--"]
# or ENTRYPOINT ["tini", "--"]
CMD ["/path/to/your/program"]headless-shell is built nightly on an Arch Linux host by the scripts in this
repository (see Chromium's Linux build instructions and the
headless README). The build runs directly on the host, and
only the resulting binaries are packaged into the container image.
Install the following with yay -S:
$ yay -S --needed \
base-devel git git-lfs python perl curl jq go bzip2 \
aarch64-linux-gnu-binutils gperf \
buildah podman qemu-user-static qemu-user-static-binfmt-
git,git-lfs,pythonandperlare used by the scripts,gclientand the Chromium build.git-lfsis required: Chromium'sthird_party/litertcontains Git LFS files, andgclient syncfails without it -
base-develprovides the build tools used by the scripts and Chromium's build (binutils,bison,flex,patch,file, and so on).stripfrombinutilsis used on the amd64 binary -
curl,jqandbzip2are used by the scripts to verify and package the build -
aarch64-linux-gnu-binutilsprovidesaarch64-linux-gnu-strip, used on the arm64 binary -
gperf, along withbisonandflex, is a build tool named in Chromium'sbuild/install-build-deps.py. The remaining packages there are for packaging, tests and distro libraries, and are not needed, as Chromium's toolchain and sysroots are downloaded bygclient -
buildah,podman,qemu-user-staticandqemu-user-static-binfmtare used to build and push the multi-arch container images -
gois needed to installverhist, which is not packaged:$ go install github.com/chromedp/verhist/cmd/verhist@latest
and it must be on the
PATHof the user running the build
# enable lingering and the timers
$ sudo loginctl enable-linger $USER
$ ./install.sh
$ systemctl enable --now --user headless-shell.timer
# run a build by hand, see all options with --help
$ ./build.sh --help
$ ./build.sh --channel stable --target amd64
# follow a build
$ journalctl --user -fu headless-shell.servicePushing requires a registry token in ~/.config/headless-shell/token.
If a build fails, headless-shell.service starts headless-shell-failure.service
(via OnFailure=), which runs notify.sh to post a message, with the tail of the
build log, to a Discord channel. Create a webhook for the
channel and store its URL in ~/.config/headless-shell/discord-webhook:
$ install -m 600 /dev/null ~/.config/headless-shell/discord-webhook
$ $EDITOR ~/.config/headless-shell/discord-webhook
# test the notification
$ ./notify.sh --unit headless-shell.service