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
.
--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 forpage.pdf()
or corresponding sources -
viewport: Viewport
, optional. See puppeteer docs forpage.setViewport()
or corresponding sources -
waitUntil: string[]
, optional. See puppeteer docs forpage.waitForNavigation()
-
timeout: number
, optional. See puppeteer docs forpage.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 forpage.screenshot()
or corresponding sources Additionally supports emulating media type viaemulateMediaType: string
optional property. -
viewport: Viewport
, optional. See puppeteer docs forpage.setViewport()
or corresponding sources -
waitUntil: string[]
, optional. See puppeteer docs forpage.waitForNavigation()
-
timeout: number
, optional. See puppeteer docs forpage.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.
To run docker containers locally you need to create deploy/docker-compose.private.yml
and add some useful env vars
(all below are optional):
---
version: "3.8"
services:
printer:
environment:
- SENTRY_DSN=<YOUR_SENTRY_DSN>
- BROWSERLESS=1
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 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. Note in such case
chrome versions used in browserless and html-to-pdf itself may diverge.