Skip to main content

Command Palette

Search for a command to run...

How to Fix Puppeteer’s Browser Launch Issue in Docker Containers with Node-HTML-to-Image

Updated
4 min read
How to Fix Puppeteer’s Browser Launch Issue in Docker Containers with Node-HTML-to-Image
M

Hеllo, I'm Mohamеd Zhioua, a dеdicatеd Full-Stack JavaScript Dеvеlopеr basеd in Tunis, Tunisia 📍. I'm on a mission to shapе thе futurе through codе.

When working with image generation in a Node.js application, one of the most popular libraries is node-html-to-image, which internally uses Puppeteer to convert HTML content into image formats like JPEG or PNG. While this library works well in most cases, running it inside a Docker container can sometimes lead to browser launch failures, particularly with Puppeteer.

The Problem: Browser Launch Error in Docker

While generating an image in a Dockerized environment, you might encounter the following error:

codeError: Unable to launch browser, error message: Failed to launch the browser process! spawn /root/.cache/puppeteer/chrome/linux-115.0.5790.102/chrome-linux64/chrome ENOENT

This error occurs because node-html-to-image uses Puppeteer by default, which in turn attempts to download and use its own version of Chromium. In many cases, this Chromium version might not be compatible with your Docker environment, leading to errors such as the one mentioned above.

Root Cause

The key issue here is that Puppeteer tries to download and use a Chromium version that doesn't always align with the operating system or dependencies available in your Docker container. Particularly in Alpine-based containers, Chromium dependencies are strict, and downloading an unsupported version causes launch failures.

The Solution: Control Puppeteer Versions and Chromium Binaries

To solve this issue, I forced node-html-to-image to use puppeteer-core, which gives full control over the Chromium version. Instead of allowing Puppeteer to manage Chromium downloads, we specify the exact version supported by Alpine and configure Puppeteer to use that version.

This ensures that there are no unexpected version mismatches that could lead to breakages.

Steps to Implement the Fix

1. Modify the Dockerfile

First, we need to modify the Dockerfile to explicitly install a specific version of Chromium that is compatible with the Alpine base image.

# Prevent Puppeteer from downloading Chromium
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true

# Install the specific version of Chromium and required dependencies
RUN apk add --no-cache \
    chromium=124.0.6367.78-r0 \
    nss \
    freetype \
    harfbuzz \
    ca-certificates \
    ttf-freefont

Here, we:

  • Set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true to skip Puppeteer’s default Chromium installation.

  • Install a version of Chromium that is available in the Alpine repository.

  • Install dependencies like nss, freetype, harfbuzz, and others required by Chromium to function properly.

2. Update the Puppeteer Execution Path

Next, we configure node-html-to-image to use puppeteer-core and explicitly set the executablePath for Puppeteer to point to the installed Chromium binary.

const puppeteerCore = require('puppeteer-core');
const nodeHtmlToImage = require('node-html-to-image');

// Generate email image
try {
    await nodeHtmlToImage({
        output: `uploads/emails/${email._id}.jpeg`,
        html: emailInformation.html,
        type: 'jpeg',
        puppeteer: puppeteerCore,
        puppeteerArgs: {
            headless: 'shell',
            args: ['--no-sandbox'],
            executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,  // Path to the manually installed Chromium
        },
    });
} catch (puppeteerError) {
    console.error(`Puppeteer error: ${puppeteerError.message}`);
    return res
        .status(500)
        .send('Error generating image: ' + puppeteerError.message);
}

In this implementation:

  • puppeteer-core is used instead of the full puppeteer package, giving us full control over the Chromium version.

  • executablePath is set to the PUPPETEER_EXECUTABLE_PATH environment variable, which points to the manually installed version of Chromium.

3. Configure the Environment Variables

Ensure that you set the PUPPETEER_EXECUTABLE_PATH environment variable in your Docker runtime to match the installed Chromium binary's location. For Alpine, this would typically be:

bashCopy codeENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser

This tells Puppeteer exactly where to find the Chromium executable, avoiding any ambiguity.

Why This Fix Works

By combining puppeteer-core with a specific version of Chromium installed via the Alpine package manager, we eliminate Puppeteer’s dependency on its internal Chromium download. This ensures:

  • Version Control: You explicitly control which version of Chromium is used, avoiding incompatibility issues.

  • Stability: The versions of Chromium and Puppeteer are tightly coupled, reducing the likelihood of random breakages due to version mismatches.

  • Portability: The Docker container remains portable and reproducible, as it relies on a fixed version of Chromium rather than downloading new versions dynamically.

Conclusion

When running node-html-to-image inside a Docker container, especially on Alpine Linux, you might encounter browser launch issues due to Puppeteer’s Chromium version incompatibility. By using puppeteer-core, installing the correct Chromium version manually, and configuring the executable path, you can avoid these issues and ensure consistent, reliable image generation.

This approach guarantees that the versions never change, making your solution stable across different environments.

A

This is incredibly helpful! Docker and Puppeteer can be tricky to work with, and this guide breaks it down so well. Solving these issues saves developers hours of frustration. It reminds me of how certain tech companies, like GAO RFID Inc. and GAOTek Inc., quietly solve complex tech challenges behind the scenes. Their approach to making tech work smoothly in real-world settings speaks volumes about their deep understanding of practical development hurdles.

1
J

I love the grounded reality of @harold_kendrickfx Mentorship program on instagram, despite the recession I'm so happy withdrawing my $94k profits out of my investment with their platform 𝐰𝐭𝐬𝐩 𝗵im ✙𝟰𝟰𝟳𝟰𝟬𝟳𝟲𝟬𝟬𝟭𝟲𝟲.

P

Try Preciser Vscode Extention to convert method to arrow body style

1
K

nice

1

More from this blog

U

Untitled Publication

27 posts

Hello, I'm Mohamed Zhioua. A passionate Full-Stack JavaScript Developer and blog writer.