ScreenshotNeo

BlogHow-to

How to Use wkhtmltoimage in a Docker Container

Run wkhtmltoimage in Docker with the right image, mounted input and output paths, and a repeatable workflow. Includes troubleshooting and a one-call API alternative.

By the ScreenshotNeo team4 October 20268 min read

wkhtmltoimage runs in a Docker container when the selected image includes the executable and its runtime libraries, and the input and output files are available at paths inside the container. Mount your working directory, then pass container paths to the command:

docker run --rm -v "$PWD:/work" -w /work <image-containing-wkhtmltoimage> \
  wkhtmltoimage input.html output.png

The placeholder image name matters: the available examples are third-party, and the sources do not establish a current official Docker image or recommended version. Check the image’s publisher, maintenance history, base OS, dependencies, fonts, and executable version before using it. wkhtmltoimage renders HTML to images using Qt WebKit and is designed to run headlessly, without a display server. See the project site and its command-line usage reference.

1. Choose and verify a container image

Docker supplies the isolation and filesystem environment; it does not install wkhtmltoimage automatically. Use an image whose provenance and contents you can review. The research located an archived third-party Docker repository and an old Docker Hub image listing, so neither should be treated as a current recommendation. The upstream project describes downloading a precompiled binary or building from source, but the sources do not identify a maintained official Docker image.

Before adopting any image, check:

  • Publisher and source: Can you inspect the Dockerfile and understand who builds and publishes it?
  • Maintenance: Is the repository active, and does the base OS still receive updates?
  • Executable and libraries: What wkhtmltoimage build and runtime dependencies are included?
  • Fonts: Are the fonts needed by your HTML installed? Missing fonts can change line breaks and layout.
  • Repeatability: Can you pin the reviewed image by immutable digest and rebuild it when dependencies need security updates?
  • Workload fit: Does it render your own HTML, assets, and output format correctly?

Containerization packages a runtime; it does not modernize the Qt WebKit renderer. Validate rendering and compatibility against your workload rather than assuming that an image name or tag guarantees either.

2. Mount the working directory and capture an HTML file

Save an input file as input.html in the directory from which you run Docker. The following is a reusable pattern. Replace the placeholder with an image you have reviewed that contains wkhtmltoimage:

docker run --rm \
  --volume "$PWD:/work" \
  --workdir /work \
  <image-containing-wkhtmltoimage> \
  wkhtmltoimage input.html output.png

The host directory is mounted at /work, so Docker’s command reads /work/input.html and writes /work/output.png. The output then appears in your host working directory. A host path such as /home/me/project/input.html is not automatically visible inside the container; mount it and refer to its container-side path.

Use a different host directory

docker run --rm \
  --volume "/path/to/project:/work" \
  --workdir /work \
  <image-containing-wkhtmltoimage> \
  wkhtmltoimage /work/input.html /work/output.png

On Windows, use a path syntax supported by your Docker environment, and make sure the directory is shared with Docker Desktop if required by your setup. If a bind mount appears empty or a file cannot be found, check the host path, path quoting, file permissions, and the path as seen from inside the container.

Pipe HTML through standard input

If the selected image supports the documented invocation, you can pipe HTML to - and write the image into a mounted directory. An archived IMIO repository documents this pattern for its image; treat it as an example of stdin and mount usage, not as a current image recommendation:

cat input.html | docker run --rm -i \
  --volume "$PWD:/work" \
  <image-containing-wkhtmltoimage> \
  wkhtmltoimage --encoding utf-8 - /work/output.jpg

The -i flag keeps standard input open. The output path still needs to be inside a mounted location if you want the file on the host.

3. Understand the paths and command options

The core Docker options in these examples are:

Option Purpose
--rm Remove the stopped container after the command exits.
--volume "$PWD:/work" Bind-mount the current host directory at /work in the container.
--workdir /work Run the command with /work as its working directory.
-i Keep standard input open for piped HTML.
<image> The image containing the executable, libraries, and any needed fonts.

The wkhtmltoimage arguments used here are:

  • input.html: an input path visible to the container, or - to read HTML from standard input.
  • output.png / output.jpg: an output path. Use a format extension supported by the build in your chosen image.
  • --encoding utf-8: the archived stdin example uses this to specify input encoding. Consult the upstream usage reference for options supported by your particular build.

This guide sticks to the options needed to demonstrate Docker execution. The exact renderer options and behavior can vary with the binary build; use the upstream command-line reference and inspect the version available in the image before relying on additional flags.

4. Make runs repeatable and limit container access

For a repeatable deployment, record the reviewed image and pin it by immutable digest rather than relying only on a mutable tag. Rebuild when the base image or dependencies need security updates, and verify the resulting binary and output against representative HTML. The research did not establish a current recommended image or version.

Mount only the directories the job needs. Avoid exposing sensitive host paths, and decide whether the renderer needs network access to load remote assets. Restricting the container’s access is a general operational safeguard; this research did not verify wkhtmltoimage-specific local-file or remote-resource behavior or a specific security vulnerability.

Docker rootless mode can run both the daemon and containers without root privileges, subject to host setup such as newuidmap, newgidmap, and subordinate UID/GID ranges. See Docker’s rootless mode documentation.

5. Troubleshoot common failures

Symptom Likely cause What to check or fix
wkhtmltoimage: not found or command not found The image does not contain the executable, or it is not on the command path. Inspect the image source and build, and verify the executable name and location. Choose an image that actually includes wkhtmltoimage.
Missing shared library or loader error The binary’s runtime dependencies are absent or incompatible with the image’s base OS. Use a build and base image with compatible dependencies. Verify the actual image rather than assuming a binary can be copied into any container.
Input file not found The host path was passed where a container path is required, or the mount source is wrong. Confirm the host directory exists, inspect the mount mapping, and use the destination path such as /work/input.html.
Output missing on the host The output was written outside the mounted directory. Write to a container path under the bind mount, for example /work/output.png.
Permission denied The container process cannot read the input or write to the mounted host directory. Check host file and directory permissions and the identity used by the container. Grant only the access needed for the job.
Fonts, spacing, or line breaks differ The image lacks fonts used by the page, or the rendering environment differs. Check installed fonts and test with representative HTML in the exact image you plan to deploy.
Remote assets are absent The page references resources the container cannot reach or the renderer did not load. Check network access, URLs, and renderer output. Do not assume a container has access to the host network or local files.
Unexpected HTML encoding The input encoding and renderer expectations differ. Save the source consistently and, for stdin workflows where supported, specify the encoding option shown in the example.
Image output is empty or incomplete The page may not have loaded as expected, or the selected build behaves differently for the workload. Capture diagnostics, verify the input and resources, and reproduce with a minimal representative HTML file. The available sources do not document a universal fix.
Build works locally but fails after an image update A tag may now point to a changed image or its base dependencies changed. Pin a reviewed digest for repeatability, then deliberately update and validate the image when rebuilding.

6. Performance, reliability, and cost considerations

The research dossier contains no verified benchmarks for particular Docker images, workload sizes, or rendering speeds. Performance depends on the selected build, page complexity, fonts, and remote resources. Measure using representative pages in the exact image and environment you intend to run. For repeatability, pin the reviewed image digest and keep the input/output paths predictable.

Reliability depends on more than whether the container starts: verify that dependencies are present, the expected assets load, and the output is readable and has the intended dimensions and appearance. The research does not establish a current official image, a current best version, or a workload-specific security guarantee.

Docker itself does not set a per-screenshot price. Account for the infrastructure and maintenance of the environment where you run the container, and for time spent reviewing image provenance, updating dependencies, and validating output. No cost or performance comparison between images was established by the sources.

7. Or skip the browser setup

If your goal is a screenshot rather than maintaining a renderer container, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request returns a PNG, JPEG, WebP, or PDF. Read the API documentation for request options and response details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month with no card.

Frequently asked questions

Does wkhtmltoimage need X11 or a display server inside Docker?

No. The project describes it as a headless renderer that does not require a display or display service.

Is there an official Docker image I should use?

The sources used for this guide do not confirm a currently maintained official image or a recommended version. Review image provenance and maintenance before choosing one.

Does running it in Docker update or modernize the renderer?

No. Docker packages and isolates an environment; the renderer remains the build included in that image.

Can I read HTML from a pipe?

The archived IMIO example demonstrates stdin with -i and the - input marker. Confirm that the image and build you select support the invocation you need.

Sources