DEV Community

Cover image for wkhtmltopdf in Docker in 2026: musl, libssl1.1, and the ways out
Vitalii Nemudryi
Vitalii Nemudryi

Posted on

wkhtmltopdf in Docker in 2026: musl, libssl1.1, and the ways out

Disclosure up front: I'm Vitalii, founder of PDFik, a hosted URL/HTML-to-PDF API. It shows up once near the end, clearly marked. The rest of this is the debugging guide I wish existed the last three times someone hit these errors.

If you run wkhtmltopdf in containers, you have probably met at least one of these three errors:

sh: /usr/local/bin/wkhtmltopdf: not found        # Alpine
wkhtmltox : Depends: libssl1.1 but it is not installable
E: Unable to locate package wkhtmltopdf          # Ubuntu 24.04 / Debian 13
Enter fullscreen mode Exit fullscreen mode

All three have the same root cause: the project is archived (January 2023, repository read-only) and the last official packages were built in May 2023 — release 0.12.6.1-3, whose newest targets are Debian 12 (bookworm) and Ubuntu 22.04 (jammy). The distros kept moving; the binaries stopped. Here is what each error actually means, the recipe that still works in 2026, and the honest exits.

Error 1: not found on Alpine — it's not about PATH

The confusing part: the file is there, ls sees it, and the shell still says not found. That message comes from the kernel failing to load the binary's interpreter: official wkhtmltopdf builds link against glibc, Alpine ships musl, and the referenced dynamic loader (/lib64/ld-linux-x86-64.so.2) does not exist on Alpine. ldd /usr/local/bin/wkhtmltopdf shows it immediately.

There is no supported way around it on Alpine today: the distro dropped its wkhtmltopdf package years ago (nothing in current stable), and gcompat shims are a lottery with a binary this large. If the container must run wkhtmltopdf, don't build it on Alpine — that fight is not worth the ~50 MB you save.

Error 2: Depends: libssl1.1 — you're installing a 2020 build on a 2023+ distro

The widely-copied Dockerfiles fetch wkhtmltox_0.12.6-1.*.deb, which links OpenSSL 1.1. Debian 12, Ubuntu 22.04+ and everything after ship OpenSSL 3 and removed libssl1.1 from the archives, so the dependency is unresolvable. (Pinning an EOL base image or hand-installing an EOL libssl to work around it means running an archived renderer on top of an unpatched TLS stack — please don't.)

The fix is simply the last release, which was built against OpenSSL 3 for bookworm and jammy.

The recipe that still works in 2026

FROM debian:bookworm-slim

ARG WKHTML_VERSION=0.12.6.1-3
RUN set -eux; \
    arch="$(dpkg --print-architecture)"; \
    apt-get update; \
    apt-get install -y --no-install-recommends curl ca-certificates; \
    curl -fsSLo /tmp/wkhtmltox.deb \
      "https://github.com/wkhtmltopdf/packaging/releases/download/${WKHTML_VERSION}/wkhtmltox_${WKHTML_VERSION}.bookworm_${arch}.deb"; \
    apt-get install -y --no-install-recommends /tmp/wkhtmltox.deb; \
    rm -f /tmp/wkhtmltox.deb; rm -rf /var/lib/apt/lists/*

# Fonts are on you: the image has almost none, and missing glyphs render as tofu.
RUN apt-get update && apt-get install -y --no-install-recommends \
      fontconfig fonts-dejavu-core fonts-noto-core fonts-noto-cjk \
    && rm -rf /var/lib/apt/lists/*
Enter fullscreen mode Exit fullscreen mode

Notes that save an afternoon:

  • dpkg --print-architecture makes the same Dockerfile work on amd64 and arm64 — 0.12.6.1-3 ships both for bookworm and jammy.
  • Fonts: wkhtmltopdf uses system fonts via fontconfig. Add the font packages your documents actually need (the Noto families cover most scripts); re-check any non-Latin text after every base-image change.
  • Security: CVE-2022-35583 (SSRF through rendered content) is permanently unfixed. Never feed wkhtmltopdf untrusted HTML, and treat the container as hostile: no metadata endpoint access, egress restricted.

Error 3: Ubuntu 24.04, Debian 13, next year's anything

There is no build for noble, trixie, or anything newer — and there never will be. The bookworm/jammy debs may keep installing on newer bases for a while if the dependency chain happens to align, but every base-image bump is now a gamble against a binary from 2023. This is the actual signal to plan the migration rather than the next workaround.

The exits, briefly

I wrote a full decision tree in the migration field guide (including where each alternative beats everything else); the short version for container people:

  • Headless Chromium in your stack — Puppeteer/Playwright (page.pdf()), or Gotenberg as a ready-made sidecar container when you want an HTTP API without writing the browser management yourself.
  • WeasyPrint — if your documents are print-CSS shaped (invoices, statements) and don't run JavaScript; no browser process at all.
  • A hosted rendering API — when you'd rather ship an HTTP call than a browser fleet. Disclosure: this category includes my product, PDFik. If the thing keeping you on wkhtmltopdf is the flags — scripts and wrappers that speak its CLI — the PDFik CLI has a compatibility mode that takes wkhtmltopdf's own command line, and its image is a few megabytes with no browser inside:
docker run --rm -e PDFIK_API_KEY -v "$PWD:/work" -w /work \
  ghcr.io/pdfik/cli wkhtmltopdf -s A4 --footer-center 'Page [page] of [topage]' \
  https://example.com report.pdf
Enter fullscreen mode Exit fullscreen mode

Every flag is mapped, accepted-with-a-warning, or refused with a reason — never silently ignored (flag-by-flag tables, option mapping). Rendering happens in our cloud on sandboxed Chromium, so the same honest caveat applies as to every hosted option: wrong for air-gapped setups, and your golden files need re-approval because the engine is not WebKit.

Package availability, archive status and CVE status last verified: 2026-08-27. If something here has rotted, tell me and I'll fix it.

Top comments (0)