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 says | Font that is used |
|---|---|
No font-family | BIZ UDPMincho (serif) |
font-family: sans-serif | BIZ UDPGothic (sans-serif) |
font-family: serif | BIZ UDPMincho |
font-family: monospace | No monospace font is bundled, so this falls back to BIZ UDPMincho |
font-weight: bold | The 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
| Path | What it does |
|---|---|
/usr/local/bin/sghtmltopdf | The executable |
/usr/share/fonts/truetype/sghtmltopdf/*.ttf | Bundled fonts |
/usr/share/doc/sghtmltopdf/fonts/OFL-*.txt | Font licences |
/work | The 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.