The reliable approach is to choose between two paths: start from Puppeteer’s maintained ghcr.io/puppeteer/puppeteer image when its Node, Linux and security model fit your deployment, or build a custom Node.js image that installs a compatible Puppeteer/browser pair and every required Chrome library. In both cases, use Node 22.12 or newer, keep Puppeteer and Chrome for Testing versions aligned, provide an init process, preserve the sandbox when possible, and give Chrome writable profile and cache directories.
Choose the right Docker strategy
Your Dockerfile determines who maintains Chrome dependencies, how much control you have over the operating system and whether the container can use Chrome’s sandbox. Decide before writing application code.
Option A: Puppeteer’s maintained image
The official image is published at ghcr.io/puppeteer/puppeteer. It contains Chrome for Testing, the required dependencies and a preinstalled Puppeteer version. Tags include latest and version-specific tags. This is normally the shortest path to a working container because browser downloads and Linux library installation are handled for you.
Pin a version-specific tag for reproducible builds rather than relying on latest. Confirm that the tag’s Node release and CPU architecture match your deployment. The documented sandboxed invocation uses Docker’s init support and adds SYS_ADMIN:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
- Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
docker run --rm --init --cap-add=SYS_ADMIN
ghcr.io/puppeteer/puppeteer:<version>
The capability is a deployment decision, not a universal requirement. Check your Kubernetes, serverless or hardened-container policy before adding it. If the platform cannot provide the required sandbox behavior, involve the platform owner instead of automatically adding --no-sandbox.
Option B: a custom Node.js image
A custom image gives you control over the Node release, Debian or Ubuntu packages, application layout, user account and browser-download policy. It also makes you responsible for tracking Chrome’s changing shared-library requirements and for keeping Puppeteer and the browser compatible.
Use Puppeteer’s current system requirements when selecting the base image. The current minimum is Node 22.12+. Chrome for Testing supports Debian/Ubuntu Linux on x64 and arm64. Verify the actual base-image architecture and Node version in CI; a Dockerfile that works on x64 may fail when built for arm64 if the selected browser package is unavailable.
A minimal custom Dockerfile
The following pattern starts with a Debian-based Node image, installs the libraries commonly required by Chrome, installs Puppeteer with its managed browser download, creates a non-root user and uses an init process. Treat the package list as a starting point: Chrome’s manifest for your exact Debian release is authoritative because dependency names change.
FROM node:22-bookworm-slim
ENV NODE_ENV=production
XDG_CONFIG_HOME=/tmp/xdg-config
XDG_CACHE_HOME=/tmp/xdg-cache
# Install an init process and Chrome's Linux runtime libraries.
# Recheck the current Chrome package manifest for your base distribution.
RUN apt-get update && apt-get install -y --no-install-recommends
dumb-init
ca-certificates
fonts-liberation
libasound2
libatk-bridge2.0-0
libatk1.0-0
libc6
libcairo2
libcups2
libdbus-1-3
libdrm2
libgbm1
libglib2.0-0
libgtk-3-0
libnspr4
libnss3
libpango-1.0-0
libx11-6
libx11-xcb1
libxcb1
libxcomposite1
libxdamage1
libxext6
libxfixes3
libxkbcommon0
libxrandr2
xdg-utils
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN useradd --create-home --shell /usr/sbin/nologin appuser
&& mkdir -p /tmp/xdg-config /tmp/xdg-cache
&& chown -R appuser:appuser /app /tmp/xdg-config /tmp/xdg-cache
USER appuser
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["node", "src/index.js"]
Do not copy this package list unchanged into a different distribution. Puppeteer’s troubleshooting guidance points to the current Chrome package manifests and recommends ldd for identifying missing libraries. If your base image is Alpine, do not assume an old Alpine recipe is still valid; verify current browser support and package names before committing to it.
package.json and browser download behavior
Install puppeteer when you want Puppeteer to download its managed browser during package installation:
Rank #2
- Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
{
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"puppeteer": "25.12.0"
}
}
Package-install scripts must be allowed to run. If your build sets ignore-scripts, Puppeteer’s browser download will not happen. Alternatively, deliberately skip the download with the PUPPETEER_SKIP_DOWNLOAD environment variable or the corresponding configuration option, install Chrome for Testing yourself, and point Puppeteer to that executable. Never combine a skipped download with an unverified system browser.
Keep Puppeteer and Chrome compatible
Puppeteer releases are paired with specific Chrome for Testing versions to protect Chrome DevTools Protocol and WebDriver BiDi compatibility. Pin a mutually compatible pair whenever reproducibility matters. The current documentation identifies Puppeteer 25.12.0 and a Chrome for Testing roll of 154.0.8037.57, with the changelog entry dated 2026-09-23; these values are time-sensitive, so check the current release information when updating the image.
With the maintained image, the preinstalled versions are selected together. With a custom image, record the Puppeteer version, browser revision and base-image digest in your build metadata. Rebuild intentionally when security updates arrive rather than allowing an unpinned package or floating image tag to change production behavior unnoticed.
Application code that works in the container
A small launch configuration is usually sufficient when the image supplies the sandbox and dependencies:
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
headless: true,
dumpio: process.env.PUPPETEER_DUMPIO === '1'
});
try {
const page = await browser.newPage();
await page.goto(process.env.TARGET_URL || 'https://example.com', {
waitUntil: 'networkidle2',
timeout: 60_000
});
await page.screenshot({path: '/tmp/page.png', fullPage: true});
} finally {
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Run it with an init process and a writable temporary directory:
docker build -t puppeteer-app .
docker run --rm --init
--cap-add=SYS_ADMIN
-e TARGET_URL=https://example.com
puppeteer-app
Use --cap-add=SYS_ADMIN only when your runtime’s sandbox policy permits it. Run as the non-root appuser shown above whenever your workload allows.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
- CanaKit Raspberry Pi 5 Essentials Starter Kit
Sandboxing, users and capabilities
Chrome’s sandbox is a major security boundary. Puppeteer’s guidance strongly discourages treating --no-sandbox as the default fix. Preserve sandboxing by running as a suitable non-root user and configuring the container runtime according to its user-namespace and capability policy. The official image documents sandboxed use with SYS_ADMIN; other environments may provide an equivalent policy or may prohibit that capability.
If a security review requires dropping all extra capabilities, ask whether the platform supports Chrome’s sandbox without them. Only after a deliberate risk assessment should you consider an alternative launch configuration, and that decision belongs in your threat model rather than in a copied Dockerfile snippet.
PID 1 and writable filesystem behavior
Use an init process
Chrome creates renderer and utility child processes. Docker sends signals to PID 1, so a Node process that does not reap children can leave zombies or fail to shut down cleanly. Use Docker’s --init flag, dumb-init as an entrypoint, or another suitable init implementation. Do not use both an image entrypoint and a runtime init accidentally without checking the resulting process tree.
Provide writable profile and cache paths
Chrome writes configuration, temporary profiles and cache data during startup. Read-only containers therefore need writable mounts or paths. Setting XDG_CONFIG_HOME and XDG_CACHE_HOME to directories under /tmp is a practical pattern when /tmp is writable:
Free tools Windows power users keep installed
One-click scans. No signup required.
docker run --rm --read-only --tmpfs /tmp:rw,noexec,nosuid,size=512m
--init --cap-add=SYS_ADMIN puppeteer-app
Size the temporary filesystem for your page workload. If screenshots or downloaded files must survive the container, write them to an explicitly mounted volume instead of relying on the ephemeral profile directory.
Diagnose failures in a fixed order
Chrome exits immediately
- Confirm the container architecture and Node release satisfy current Puppeteer requirements.
- Run the browser binary and inspect dynamic dependencies with
ldd. A line ending in “not found” identifies a missing shared library. - Compare missing libraries with the current Chrome package manifest for the exact Debian or Ubuntu release, then rebuild without stale package names.
“No usable sandbox” or permission errors
- Check whether the container runs as root and whether the runtime permits the required user namespaces or capability.
- Test the documented sandboxed configuration with the appropriate capability policy.
- Do not jump directly to
--no-sandbox; disabling it changes the security properties of the workload.
Failure in a read-only container
- Ensure
XDG_CONFIG_HOME,XDG_CACHE_HOMEand any explicituserDataDirpoint to writable locations. - Mount a suitably sized temporary filesystem at
/tmp, or provide a writable volume for artifacts.
Zombie processes or hangs during shutdown
- Add Docker’s
--initor usedumb-initas the entrypoint. - Always close the browser in a
finallyblock, including when navigation or screenshot code throws.
Navigation timeouts and blank output
- Set an explicit navigation timeout appropriate to the page and choose a wait condition such as
networkidle2only when the site eventually becomes idle. - Check DNS, outbound network policy, TLS certificates and proxy settings inside the container.
- Use
dumpio: trueto forward browser output. SetNODE_DEBUG="puppeteer:*"for Puppeteer protocol diagnostics; logs can contain URLs, headers or page data, so keep them out of public CI artifacts.
Architecture, builds and operations
Build for the deployment architecture
Chrome for Testing’s documented Linux targets include x64 and arm64 on Debian/Ubuntu. Build and run the same architecture you will deploy, or use an explicit multi-platform build pipeline. Verify that every native package and browser artifact is available for that architecture before releasing.
Rank #4
- All-in-One Complete Kit: This SANOOV RPi 5 bundle comes with Raspberry Pi 5 4GB RAM single board, active cooler, durable ABS case and screwdriver. No extra parts needed, ready to use right out of the box for beginners and hobbyists
- Powerful Single Board Computer: Equipped with 4GB RAM and high-performance processor, delivers fast running speed for 4K playback, AI projects, programming and daily computing tasks. SANOOV for raspberry pi 5 4GB is equipped with broadcom 64 quad-core Arm Cortex A76 processor with gigabit ethernet and upgraded with IEEE 802.11ac Wi-Fi, Bluetooth 5.0 dual-band 2.4Ghz and 5Ghz and Power Over Ethernet (POE). Upgrading delivers 2-3 x speed vs Pi 4, redefining the experience
- Efficient Active Cooler: Effectively lowers operating temperature and prevents performance throttling. Runs quietly even under long-time heavy load, ensures stable operation all day long. SANOOV RPi 5 4GB kit offer an active cooler, which combines an aluminium heatsink with a high-performance PWM fan. Active cooler is fully compatible with the Pi OS, which can effectively reduce the temperature of RPi5 and ensure its good performance during long-term high load operation
- Sturdy ABS Protective Case: Well-fitted for Raspberry Pi 5 board, can be secured with 4 screws to effectively protect the Pi 5 motherboard from damage, reserves full access to all ports and buttons. SANOOV uses ABS material to produce the case, which has a softer texture and feel. Meanwhile, SANOOV case adopts a layered design for easy disassembly and installation. (Tip: The Case cannot install M.2 HAT Add on Board and Solid State Drive!)
- Wide Application & Full Compatibility: Seamlessly compatible with official OS and mainstream peripheral accessories for Raspberry Pi 5. Whether you are a beginner, student, electronics hobbyist or professional developer, this all-in-one kit meets your diverse needs. It excels in IoT projects, robotics design, retro gaming devices, home media servers and other DIY creations. Backed by a large global community, you can easily find guides, technical support and shared projects online
Make builds reproducible
- Pin the Puppeteer version and, where possible, the official-image tag or base-image digest.
- Keep the browser revision paired with that Puppeteer release.
- Run a smoke test that launches Chrome, opens a controlled URL and writes a screenshot to a writable path.
- Rebuild on a planned schedule for Node, Chrome and Debian security updates.
Control resource use
Each browser instance consumes memory and creates multiple processes. Reuse a browser for several pages when isolation permits, close pages promptly and bound concurrency with a queue. Give the container enough shared memory for the pages you process; if your runtime’s default shared-memory mount is small, configure it deliberately rather than masking crashes with unsafe flags. Set page and browser timeouts so a failed navigation cannot occupy a worker forever.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a clean website image rather than maintaining Chrome in Docker, ScreenshotNeo returns a screenshot or PDF from one request. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.
See the complete parameter reference in the ScreenshotNeo documentation. A direct call looks like this:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
There is a free allowance of 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan. Create a free ScreenshotNeo account to try it without setting up a browser container.
FAQ
Should I use the official Puppeteer image or Node.js base image?
Use the official image when its preinstalled browser, Node release, architecture and capability model fit your environment. Choose a custom image when you need precise OS packages, a different application layout or an independently managed browser.
Can I use Puppeteer with a system-installed Chrome?
Yes. Skip Puppeteer’s browser download intentionally, install a compatible browser yourself and configure Puppeteer with that executable. Verify the browser version against the Puppeteer release rather than assuming any Chrome installation is compatible.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Why does a container need --init?
Chrome creates child processes. An init process helps PID 1 forward signals and reap those children, improving shutdown and long-running reliability.
Best Value
- 【What you Get】You will get 1*Pi 5 8GB Single Board,1*RasTech Case,1*Active Cooler,1*Screwdriver,1*Installation instructions,12-month free warranty, lifetime service, 24-hour prompt and friendly response.
- 【More Connectors】There are two USB 3.0 ports(5Gbps simultaneously) and two USB 2.0 ports, which triple total bandwidth ,support any combination of up to two cameras or displays. Peak SD card performance is doubled through support for the SDR104 high-speed mode. It provides a smooth desktop experience for you. Offer Gigabit Ethernet and a PCIe interface, along with dual-band Wi-Fi and Bluetooth 5.0/BLE wireless capability. The RasTech Pi 5 Kit use the new 27W 5.1V 5A USB-C power connector.
- 【 Support Dual 4Kp60 Display 】Each of the two microHDMI sockets can control a 4K display at 60 Hertz, now support HDR, offering super HD video for media streaming projects. RPi 5 is the first RPi model that comes with a PCI Express port (PCIe 2.0 x1 with 500 MB/s) to attach SSDs (requires separate M.2 HAT).
- 【 Excellent Chips And Applications】Pi 5 is a full-size Pi computer using silicon built in-house at Pi. The RP1 “southbridge” provides the bulk of the I/O capabilities for Pi 5. Pi 5 is more friendly and convenient in the development of Internet of Things, Web development, machine identification, automatic control and other electronic equipment applications and network.
- 【 Faster CPU, Better GPU 】 Pi 5 features a Broadcom BCM2712 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz, it delivers a 2–3× increase in CPU performance relative to RaspberryPi 4. The 800MHz VideoCore VII GPU is compatible to OpenGL ES 3.1 and Vulkan 1.2, substantial uplift in graphics performance. Pi 5 Offers lightning-fast CPU speed, a PCI Express interface, a Real Time Clock (RTC) and a power button and runs significantly cooler than Pi 4.
Is --no-sandbox ever acceptable?
It is a security trade-off, not a routine Docker setting. First resolve the runtime’s user, namespace and capability policy so Chrome can remain sandboxed; document any exception in your deployment threat model.
Frequently Asked Questions
Should I use the official Puppeteer image or Node.js base image?
Use the official image when its preinstalled browser, Node release, architecture and capability model fit your environment. Choose a custom image when you need precise OS packages, a different application layout or an independently managed browser.
Can I use Puppeteer with a system-installed Chrome?
Yes. Skip Puppeteer’s browser download intentionally, install a compatible browser yourself and configure Puppeteer with that executable. Verify the browser version against the Puppeteer release rather than assuming any Chrome installation is compatible.
Recommended Free Tools
Why does a container need –init?
Chrome creates child processes. An init process helps PID 1 forward signals and reap those children, improving shutdown and long-running reliability.
Is –no-sandbox ever acceptable?
It is a security trade-off, not a routine Docker setting. First resolve the runtime’s user, namespace and capability policy so Chrome can remain sandboxed; document any exception in your deployment threat model.
The Bottom Line
For the least maintenance, pin a compatible tag of Puppeteer’s official image. For maximum control, build from Node 22.12+ on a supported Debian/Ubuntu base, install current Chrome libraries, preserve the sandbox, add an init process and provide writable profile paths.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

