Skip to content
Latchkey

How to Install Headless Chromium in CI

Chromium runs almost anywhere - once its long list of shared libraries is present. Slim CI images ship almost none of them.

Whether driven by Puppeteer, Playwright, or Selenium, headless Chromium needs the same OS libraries (NSS, GTK/GBM, fonts) and usually --no-sandbox in containers.

Why it fails in CI

  • Missing libnss3/libgbm/fonts → Chromium exits immediately on launch.
  • The sandbox cannot initialize inside an unprivileged container.
  • No fonts installed → blank or boxes in screenshots.

Install it reliably

Install the dependency set (or distro Chromium, which pulls them in), and launch headless with the right flags for a container.

Terminal
# distro Chromium pulls most deps automatically
apt-get update && apt-get install -y chromium fonts-liberation

# or install just the deps for a managed Chromium download:
apt-get install -y \
  libnss3 libatk-bridge2.0-0 libgbm1 libasound2 \
  libxshmfence1 libxkbcommon0 fonts-liberation

chromium --headless --no-sandbox --disable-gpu --dump-dom https://example.com

Cache & speed

Bake Chromium and its libraries into a custom runner image so they are not reinstalled each run. Chromium launches can be flaky; auto-retry of transient crashes and larger managed runners reduce noise.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/.cache/ms-playwright
    key: chromium-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}

Common errors

  • error while loading shared libraries: libnss3.so → install the dependency set above.
  • Failed to move to new namespace / No usable sandbox → add --no-sandbox in containers.
  • Blank screenshots → install a font package.

Key takeaways

  • Chromium needs NSS/GTK/GBM libs and at least one font package.
  • Use --no-sandbox in unprivileged containers.
  • Bake the browser and libs into a custom image to avoid per-run installs.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →