Build your image
PDF Server is distributed as a base Docker image. You build your service by layering your templates on top of it.
With Docker
# Dockerfile
ARG PDF_SERVER_IMAGE=registry.gitlab.com/c0va23/pdf-server:latest-chromium
FROM ${PDF_SERVER_IMAGE}
ADD templates templates
ADD compositions compositions
docker build -t my-pdf-service .
docker run --rm -it -p 9999:9999 my-pdf-service
The base image's entrypoint runs the server, loading templates/ and
compositions/ from the working directory. Configure everything else via
environment variables (see the CLI & config reference).
With docker buildx bake
For a multi-arch push, drive the same Dockerfile with docker buildx bake:
# docker-bake.hcl
target "my-image" {
dockerfile = "Dockerfile"
tags = ["registry.example.com/my-pdf-service:latest"]
platforms = ["linux/amd64", "linux/arm64"]
}
docker buildx bake my-image --push
Base image
The published base image (…:latest-chromium) ships Chromium and supports both
the runner and page factory modes. See
Deployment for factory modes and pool tuning.
Nested (recursive) templates
If you organise templates into nested folders, enable recursive loading so names
like invoices/eu are discovered:
-e TEMPLATES_RECURSIVE=true
Verify in CI
Fail the build if any template or example cannot render:
pdf-server --templates-dir ./templates --compositions-dir ./compositions validate
Run it
Your service now serves the HTTP API:
curl -X POST -H 'Content-Type: application/json' \
-d '{"number":"A-1"}' \
http://localhost:9999/templates/invoice/render > invoice.pdf
Put an authenticating reverse proxy in front of it and apply the hardening checklist before exposing it.