This project is a lightweight Puppeteer/Chromium docker image ready to launch out of the box.
Supports Node.js 20, 22, and 24 on Alpine Linux.
Architectures:
amd64andarm64.
docker pull icedrone/docker-puppeteer:latestInstall puppeteer-core (not puppeteer) since the image ships with system Chromium:
npm install puppeteer-coreExample:
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.launch(
{
executablePath: '/usr/bin/chromium-browser',
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
}
);Note:
--no-sandboxis required because Chromium's sandbox needs kernel capabilities not available in most containers. The container already runs as a non-root user (pptruser) which limits the blast radius. Avoid processing untrusted HTML/URLs without additional isolation.
--disable-dev-shm-usageis recommended to prevent Chromium crashes caused by Docker's default 64MB/dev/shmlimit.
The following are already set in the image — no need to configure them manually:
| Variable | Value |
|---|---|
CHROME_BIN |
/usr/bin/chromium-browser |
PUPPETEER_EXECUTABLE_PATH |
/usr/bin/chromium-browser |
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD |
true |
PUPPETEER_SKIP_DOWNLOAD |
true |
Noto Sans CJK, Noto Color Emoji, DejaVu, FreeFonts, Inconsolata, Linux Libertine — supporting CJK characters, emoji, and Latin scripts out of the box.
- Runs as non-root user
pptruser(UID 1001) - Working directory:
/app - Uses
tinias PID 1 for proper signal handling - Available on both Docker Hub and GitHub Container Registry:
docker pull icedrone/docker-puppeteer:latest docker pull ghcr.io/icedrone/docker-puppeteer:latest
FROM icedrone/docker-puppeteer:latestFROM icedrone/docker-puppeteer:latest
COPY --chown=pptruser:pptruser . .
RUN npm ci
CMD ["node", "index.js"]Note: Always use
--chown=pptruser:pptruserwithCOPYandADDinstructions. The image runs as non-root userpptruser, so files copied without--chownwill be owned by root and may not be readable or writable by the application.
All tags include a Node version suffix. Short aliases without -alpine are also available since Alpine is the default.
Bare semver tags (e.g. 1.0.0) always point to the default Node version (currently 22 Alpine).
latest— default image (currently Node 22 Alpine)1.0.0— specific semver release (default Node version)1.0— latest patch for a given major.minor1— latest minor and patch for a given major22or22-alpine— latest build for Node 22latest-22orlatest-22-alpine— same as above, explicit form1.0.0-22-alpine— specific semver release pinned to a Node versionsha-a1b2c3d-22-alpine— built from a specific commit
Replace 22 with 20 or 24 for other Node versions.
The project uses a multi-layer test strategy. All tests run inside the built Docker image.
# Build the image locally
docker build -t docker-puppeteer:local .
# Container structure tests (metadata, binaries, fonts)
container-structure-test test --image docker-puppeteer:local --config test/structure-test.yaml
# Runtime validation with dgoss
dgoss run docker-puppeteer:local
# Integration tests (Puppeteer rendering, PDF, screenshots)
docker run --rm -v "$(pwd)/test/integration:/app" -w /app docker-puppeteer:local sh -c "npm ci && npm test"See CONTRIBUTING.md for full setup instructions.
If you ❤️ the project feel free to help and contribute. Pull-requests are welcome. See CONTRIBUTING.md for guidelines.
MIT © License