Dockerized Puppeteer PDF Printer

Thu Mar 30 2023

Puppeteer provides solution to print PDF from web page. However, it requires a lot of dependencies to be installed. This post shows how to build a Docker image to run Puppeteer to print or generate PDF file.

Nodejs App To Print PDF Using Puppeteer

Puppeteer is a nodejs library that provides API to control headless Chrome or Chromium. Here's a piece of code to print PDF from a web page.

TypeScript
|
import { PDFOptions } from './../../node_modules/puppeteer-core/lib/cjs/puppeteer/common/PDFOptions.d'; import puppeteer from 'puppeteer'; const defaultPDFOptions: PDFOptions = { format: 'A4', margin: undefined, }; export type WebPageToPdfArgs = { url: string, filepath: string, pdfOptions?: PDFOptions, }; const webPageToPdf = async ({ url, filepath, pdfOptions }: WebPageToPdfArgs) => { const browser = await puppeteer.launch({ headless: true, executablePath: 'google-chrome-stable', // use google-chrome-stable in docker args: ['--no-sandbox'], // required for running in docker as root }); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle0' } ); await page.pdf({ ...(pdfOptions || defaultPDFOptions), path: filepath, }); await browser.close(); return filepath; }; export default webPageToPdf;

Build a Docker Image to Run Puppeteer as a Service

Puppeteer uses Chromium or Chrome to print PDF, and it also requires a lot of dependencies to be installed. In the Dockerfile I added all the dependencies required by Puppeteer.

But when I try to run puppeteer in docker with bundled Chromium, an error occurred saying Chromium can not be found. So I decided to use google-chrome-stable instead of the bundled chromium.

Here's the Dockerfile.

Dockerfile
|
FROM shinchven/node:16-deployment # install dependencies for chrome and puppeteer RUN apt update && apt install -y \ ca-certificates \ fonts-liberation \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libc6 \ libcairo2 \ libcups2 \ libdbus-1-3 \ libexpat1 \ libfontconfig1 \ libgbm1 \ libgcc1 \ libglib2.0-0 \ libgtk-3-0 \ libnspr4 \ libnss3 \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libstdc++6 \ libx11-6 \ libx11-xcb1 \ libxcb1 \ libxcomposite1 \ libxcursor1 \ libxdamage1 \ libxext6 \ libxfixes3 \ libxi6 \ libxrandr2 \ libxrender1 \ libxss1 \ libxtst6 \ lsb-release \ wget \ xdg-utils \ curl # install google-chrome-stable, to use it, set executablePath to 'google-chrome-stable' in nodejs code RUN curl -LO https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb RUN apt-get install -y ./google-chrome-stable_current_amd64.deb RUN rm google-chrome-stable_current_amd64.deb # copy files WORKDIR /usr/src/app COPY server /usr/src/app # Put font files in /usr/share/fonts to fix character issues COPY fonts/MSYH.ttc /usr/share/fonts/ # build app RUN npm install && npm run compile ENV NODE_ENV=production EXPOSE 3030 CMD ["node","lib/index.js"]

web2pdf

With the code above, I created a GitHub repository web2pdf and a docker image shinchven/web2pdf. You can use it directly or build one of your own.