Recently I was working on a project that required me to run a headful Chrome instance (via Puppeteer) inside a Docker container. To keep the container as small and lightweight as possible, I avoided installing a desktop environment inside the container.
What originally seemed like a simple task turned out to be a bit more complicated than I expected. Anyway, after some trial and error, I managed to get it working.
The Dockerfile
The Dockerfile is pretty straightforward. It’s based on the official
debian:latest
image.
FROM debian:latest
ENV DEBIAN_FRONTEND=noninteractive
# Install dependencies
RUN apt-get update && \
apt-get install -y \
xvfb \
chromium
ADD xvfb-chromium /usr/bin/xvfb-chromium
RUN ln -s /usr/bin/xvfb-chromium /usr/bin/google-chrome && \
ln -s /usr/bin/xvfb-chromium /usr/bin/chromium-browser && \
chmod +x /usr/bin/xvfb-chromium && \
chmod +x /usr/bin/google-chrome
Be sure to include line 3, ENV DEBIAN_FRONTEND=noninteractive
. This
will prevent the installation of any dependencies from hanging.
On line 11, we add a script called xvfb-chromium
to the container (make sure it’s in the same directory as the Dockerfile).
This script will be used to launch Chrome. This is script is taken from
Atlassian’s docker-chromium-xvfb repository.
#!/bin/bash
_kill_procs() {
kill -TERM $chromium
wait $chromium
kill -TERM $xvfb
}
# Setup a trap to catch SIGTERM and relay it to child processes
trap _kill_procs SIGTERM
XVFB_WHD=${XVFB_WHD:-1280x720x16}
# Start Xvfb
Xvfb :99 -ac -screen 0 $XVFB_WHD -nolisten tcp &
xvfb=$!
export DISPLAY=:99
chromium --no-sandbox $@ &
chromium=$!
wait $chromium
wait $xvfb
With this, you should now be able to run a headful Chrome instance inside the container, for example, via Puppeteer.