Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Docker

An official image with Japanese fonts bundled is published on ghcr.io. It is the easiest way to run the server mode as a long-lived process.

docker pull ghcr.io/waka/sghtmltopdf:latest

The supported platforms are linux/amd64 and linux/arm64, both glibc; musl systems such as Alpine are out of scope. The same tag serves both.

Running it as a server

Started with no arguments, it runs as the HTTP server.

docker run --rm -p 8080:8080 ghcr.io/waka/sghtmltopdf
curl --data-binary @invoice.html \
     'http://127.0.0.1:8080/pdf?page-size=A4' \
     -o invoice.pdf

Inside the container it listens on --listen 0.0.0.0:8080. The server mode defaults to 127.0.0.1, so that nothing is exposed by accident, but that address cannot be reached from outside the container, so the image sets the flag explicitly in its CMD.

To change the startup options, write the command out yourself, starting from server.

docker run --rm -p 8080:8080 ghcr.io/waka/sghtmltopdf \
    server --listen 0.0.0.0:8080 --workers 4 --max-body-size 52428800

There is no authentication and no TLS. Put a reverse proxy in front of it before exposing it to the outside.

docker compose

services:
  pdf:
    image: ghcr.io/waka/sghtmltopdf:0.1
    ports: ["8080:8080"]
    healthcheck:
      test: ["CMD", "sghtmltopdf", "--version"]
      interval: 30s

curl is not in the image, so either use --version as the health check as shown, or call GET /healthz from outside, for example from your load balancer.

Running it as a CLI

The ENTRYPOINT is the binary itself, so passing arguments runs it as the CLI.

docker run --rm -v "$PWD:/work" -w /work --user "$(id -u):$(id -g)" \
    ghcr.io/waka/sghtmltopdf invoice.html -o invoice.pdf

The container does not run as root; it runs as UID 10001. When writing a PDF into a directory on the host, match the host owner with --user, as shown above.

Bundled fonts

The image contains BIZ UDPGothic and BIZ UDPMincho, Regular and Bold, four faces in total, under the SIL Open Font License 1.1. The full licence text is at /usr/share/doc/sghtmltopdf/fonts/ inside the image.

What the CSS saysFont that is used
No font-familyBIZ UDPMincho (serif)
font-family: sans-serifBIZ UDPGothic (sans-serif)
font-family: serifBIZ UDPMincho
font-family: monospaceNo monospace font is bundled, so this falls back to BIZ UDPMincho
font-weight: boldThe real Bold face of each family, not synthesised bold

Because the fonts are fixed, the same HTML always produces the same PDF, apart from the creation timestamp inside the file. Not depending on the host’s font setup is one of the reasons to use the image.

To use a different font, mount it and pass it with --font. It takes precedence over the bundled fonts.

docker run --rm -v "$PWD:/work" -w /work --user "$(id -u):$(id -g)" \
    ghcr.io/waka/sghtmltopdf invoice.html -o invoice.pdf \
    --font fonts/YourFont-Regular.ttf --gothic-font fonts/YourFont-Regular.ttf

What is in the image

PathWhat it does
/usr/local/bin/sghtmltopdfThe executable
/usr/share/fonts/truetype/sghtmltopdf/*.ttfBundled fonts
/usr/share/doc/sghtmltopdf/fonts/OFL-*.txtFont licences
/workThe default working directory

The base is debian:bookworm-slim with no extra system packages. Even ca-certificates is unnecessary, because the TLS root certificates are embedded in the binary.