Headful Chrome Inside a Docker Container

How to run a headful Chrome instance inside a Docker container without installing a desktop environment


December 2, 2022

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.

Dockerfile
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.

xvfb-chromium
#!/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.