Heuristic:Puppeteer Puppeteer Headless Linux Requirements
| Knowledge Sources | |
|---|---|
| Domains | Infrastructure, Debugging, DevOps |
| Last Updated | 2026-02-11 23:30 GMT |
Overview
Running Puppeteer on Linux servers and CI requires headless mode or `xvfb-run`, sandbox configuration, and system font packages. Docker and Alpine Linux have specific known issues.
Description
Puppeteer on Linux (especially headless servers, CI runners, and containers) faces several environment-specific challenges: no display server for headful mode, Chrome sandbox restrictions, missing system fonts, `/dev/shm` size limitations in Docker, and AppArmor restrictions on Ubuntu 23.10+. The codebase includes explicit detection and error messages for these conditions.
Usage
Apply this heuristic when deploying Puppeteer to Linux servers, CI/CD pipelines, or Docker containers. Symptoms include: browser launch failures, "Missing X server" errors, sandbox errors, blank screenshots due to missing fonts, Chrome crashes from `/dev/shm` exhaustion, and timeout errors on Alpine Linux.
The Insight (Rule of Thumb)
- Action 1 (Display): Use `headless: true` (default) or `headless: 'shell'` on headless servers. For headful mode, use `xvfb-run node script.js`.
- Action 2 (Sandbox): Configure the Chrome sandbox properly rather than using `--no-sandbox`. If sandboxing is impossible, set `args: ['--no-sandbox', '--disable-setuid-sandbox']` but understand the security implications.
- Action 3 (Docker): The default flag `--disable-dev-shm-usage` handles `/dev/shm` limitations. Use the official Puppeteer Docker image or install system deps with `npx puppeteer browsers install chrome --install-deps`.
- Action 4 (Fonts): Install font packages: `fonts-ipafont-gothic`, `fonts-wqy-zenhei`, `fonts-thai-tlwg`, `fonts-khmeros`, `fonts-kacst`, `fonts-freefont-ttf`.
- Action 5 (Alpine): Avoid Alpine 3.20 due to Chromium timeout issues. Use Alpine 3.19 or Debian-based images.
- Trade-off: `--no-sandbox` removes a security boundary. `--disable-dev-shm-usage` writes to `/tmp` instead which may be slower. Alpine is smaller but has known Chromium issues.
Reasoning
Missing X Server: Chrome in headful mode requires a display server. Headless servers have no X11/Wayland. Puppeteer detects this from Chrome stderr and provides a clear error message.
Sandbox: Chrome uses Linux namespaces for sandboxing. Docker containers and some CI environments restrict namespace creation. Ubuntu 23.10+ AppArmor blocks Chrome for Testing from using namespaces by default.
/dev/shm: Docker defaults to 64MB for `/dev/shm`. Chrome uses shared memory heavily; exhausting it causes tab crashes. The `--disable-dev-shm-usage` flag (included by default in Puppeteer) routes shared memory to `/tmp`.
Alpine Linux: The Chromium build in Alpine 3.20 has known timeout issues (Puppeteer issues #11640, #12637, #12189).
From `packages/puppeteer-core/src/node/BrowserLauncher.ts:240-243`:
if (logs.includes('Missing X server') && options.headless === false) {
throw new Error(
'Missing X server to start the headful browser. ' +
'Either set headless to true or use xvfb-run to run your Puppeteer script.'
);
}
Process singleton error from `packages/puppeteer-core/src/node/BrowserLauncher.ts:227-238`:
if (
logs.includes('Failed to create a ProcessSingleton for your profile directory') ||
(process.platform === 'win32' &&
existsSync(join(launchArgs.userDataDir, 'lockfile')))
) {
throw new Error(
`The browser is already running for ${launchArgs.userDataDir}. ` +
'Use a different `userDataDir` or stop the running browser first.'
);
}
Docker Dockerfile evidence from `docker/Dockerfile`:
FROM node:24-bookworm
ENV LANG=en_US.UTF-8
RUN apt-get install -y fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg \
fonts-khmeros fonts-kacst fonts-freefont-ttf dbus dbus-x11