Microservice for generating PDF and screenshots from either provided HTML or a URL.
Uses puppeteer and
headless-chrome.
Written in typescript
compiled by webpack and
dependencies managed by yarn 3.
Docker file is inspired by zenika/alpine-chrome.
⚠️ Disclaimer: chrome is run with --no-sandbox flag meaning it should NOT be run as a public service.
It's only meant to be run as a microservice in your private network where you control what you are printing.
See puppeteer docs
or zenika/alpine-chrome
why we have --no-sandbox.
You can find prebuilt docker images on dockerhub. Each tag on
github should have corresponding docker image tag on dockerhub. For each commit to main branch a corresponding tag
starting with git- prefix is created. This can be used if you want to use some latest version that was not yet released.
Project is designed to be run as a docker container. It exposes port 4000 by default but can be configured to use
another port using PORT env variable. After starting container an express server will start listening at this port
providing some HTTP endpoints.
For details on running it locally please scroll to Development section.
Note: only POST methods allow passing html instead of an url. Both url and html are optional meaning if none
is provided about:blank will be printed.
GET /pdf?url=<url>&filename=<filename>
accepts the following query parameters:
url: string, required
filename: string, optional.
Simplest query can be similar to: /pdf?url=https://example.com
GET /screenshot?url=<url>&filename=<filename>
accepts the following query parameters:
url: string, required
filename: string, optional.
Simplest query can be similar to: /screenshot?url=https://example.com
a POST accepting JSON body with following parameters:
url: string, optional. Publicly accessible url of a page to be captured.
html: string, optional. HTML page with all resources either embedded or referenced using absolute urls.
pdfOptions: PDFOptions, optional.
See puppeteer docs for page.pdf()
or corresponding sources
viewport: Viewport, optional.
See puppeteer docs for page.setViewport()
or corresponding sources
waitUntil: string[], optional.
See puppeteer docs for page.waitForNavigation()
timeout: number, optional.
See puppeteer docs for page.setDefaultNavigationTimeout()
Simplest payload can be similar to:
{"url": "https://example.com"}
a POST accepting JSON body with following parameters:
url: string, optional. Publicly accessible url of a page to be captured.
html: string, optional. HTML page with all resources either embedded or referenced using absolute urls.
screenshotOptions: ScreenshotOptions, optional.
See puppeteer docs for page.screenshot()
or corresponding sources
Additionally supports emulating media type via emulateMediaType: string optional property.
viewport: Viewport, optional.
See puppeteer docs for page.setViewport()
or corresponding sources
waitUntil: string[], optional.
See puppeteer docs for page.waitForNavigation()
timeout: number, optional.
See puppeteer docs for page.setDefaultNavigationTimeout()
Simplest payload is the same as for the POST /pdf method
Exports prometheus metrics.
Prints a dead simple test PDF file to check if the service is healthy.
Prints this readme
We are using taskfile for running local commands. Run task to see a list of available commands.
You can develop locally without the need to run docker container (task run). Puppeteer should automatically pick up chrome
installed locally. The only requirement is to have chrome installed, but you are web developer already using chrome,
aren't you 😉.
Otherwise you can run task run to develop in docker container.
deploy/docker-compose.private.yml and add some useful env vars
(all below are optional):
```yamlversion: "3.8"
services:
printer:
environment:
- SENTRY_DSN=
If you provide `SENTRY_DSN` all errors from local env will be reported to sentry.
You can run `task run:debug` which will start useful
[browserless/chrome](https://github.com/browserless/chrome) image. If you provide `BROWSERLESS=1` in your
docker compose file printer will start using browserless container instead of bundled chrome.
When using browserless you can also do nice debugging at [localhost:3000](http://localhost:3000/). Note in such case
chrome versions used in browserless and html-to-pdf itself may diverge.