Docker Runner
This page records the Docker Runner checked on 2026-10-17. Reference example output is produced in this Debian Bookworm container. The repository is not public yet, so the container definition is included below.
The container copies Go, Node.js, Elixir, and Erlang/OTP from official language images, and uses the matching Python image as its base. libvips is compiled from the upstream source tarball at a pinned version and checksum. The container uses that in-image library rather than the distribution package.
For the version comparison table, see the version compatibility matrix. On your own machine, trust the versions printed by install and verify.
Locked versions
Section titled “Locked versions”| Role | Component | Version | Notes |
|---|---|---|---|
| Container | Go | 1.27.0 | From golang:1.27.0-bookworm |
| Container | Node.js | 24.14.1 | Copied from the official Node image for sharp |
| Container | pnpm | 12.11.2 | Activated through Corepack |
| Container | Python | 3.14.5 | Base image python:3.14.5-bookworm |
| Container | Elixir / OTP | 1.20.4 / 29.1.2 | From hexpm/elixir:1.20.4-erlang-29.1.2-debian-bookworm-20261005 |
| Container | libvips | 8.17.3 | Built from source in the container and installed to /usr/local |
| Reference | govips | v2.20.0 | Linked to libvips 8.17.3 above |
| Comparison | pyvips | 3.2.0 | Linked to the same libvips 8.17.3 |
| Comparison | vips CLI | 8.17.3 | Shares that library with the reference |
| Comparison | sharp | 0.35.5 | Uses libvips 8.18.7 bundled in the npm package |
| Comparison | Image / Vix | 0.72.0 / 0.42.0 | Linked to the same libvips 8.17.3; covers a subset of examples |
How an example finishes
Section titled “How an example finishes”- The container supplies the compilers and language runtimes in the table, plus libvips 8.17.3 built from source.
- Go/govips is the reference implementation. It links that libvips, runs the operation on one shared input, and writes the image together with metadata such as version and dimensions.
- sharp, pyvips, and the vips CLI each run the same processing intent. Elixir Image links the same libvips through Vix, with
VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPSat compile time and at runtime. Image currently covers the thumbnail, format conversion, geometry, alpha, and colour examples. Those runs stay an extra comparison entry, recorded separately from the govips reference. - Each output records format, dimensions, bands, and byte size. Matching byte size means the files are the same length. Whether the pixels match stays a separate, later conclusion.
- Those outputs stay with their format, dimensions, and version metadata for later comparison.
The image’s default command only prints the pnpm version. An example run replaces that command with the command for the interface being executed. The image sets VIPS_RUNNER=1 to mark that the process is inside this example environment. The variable does not change how libvips loads files.
What the image contains
Section titled “What the image contains”- Go, Node.js, Elixir, and OTP are copied into the final image from the official images above, so one base image does not have to install four language toolchains itself.
- The Node.js image contributes
nodeand the npm modules. Corepack activates pnpm 12.11.2. libsctp1keeps OTP from warning about a missing SCTP library at startup.- pyvips 3.2.0 is installed at the end of the image build, and the build asserts that it loads libvips 8.17.3.
- Elixir and OTP stay in the image. Image and Vix are compiled when an example needs them, and they link the libvips inside the image rather than the prebuilt library Vix bundles by default. The image does not install FFmpeg, Nx, evision, or image_vision.
- The image leaves
VIPS_BLOCK_UNTRUSTEDunset. Image sets that switch itself when the application starts. A global environment value would also change how govips, pyvips, and the CLI load files. - Text examples use the installed DejaVu Sans, and the image build refreshes the font cache before it finishes.
Loader choices
Section titled “Loader choices”libvips is installed under /usr/local as a release build, with dynamic modules disabled. The build checks that the JPEG, WebP, PNG, SVG, and HEIF loaders appear in the output of vips -l foreign.
Capabilities used by the current examples stay enabled: JPEG, PNG, WebP, TIFF, SVG (librsvg), Pango/Cairo text, fontconfig, HEIF, cgif, libspng, OpenJPEG, libimagequant, libarchive, libexif, lcms2, and fftw3. HEIF stays enabled, without a dynamic module. A missing AVIF/HEIF loader then shows up in the loader list, instead of failing only on a later call.
These loaders are disabled: ImageMagick, OpenSlide, FITS, NIfTI, OpenEXR, Poppler, PDF, JPEG XL, plus quantizr and Highway. Current examples use JPEG, PNG, WebP, TIFF, and SVG. ImageMagick is disabled so a distribution Magick loader cannot insert itself ahead of the native JPEG, PNG, and WebP savers and change foreign-loader priority.
Dockerfile
Section titled “Dockerfile”This is the example container definition as of 2026-10-17.
# Recipe runner for the VIPS Handbook.# Versions come from toolchain.lock.yml. Node is pinned to 24.14.1, the patch# already checked on the reference workstation; the lock file accepts any Node 24.## Do not set VIPS_BLOCK_UNTRUSTED here. elixir-image/image sets it when that# application starts, and a global setting would change govips, pyvips, and CLI loads.
FROM golang:1.27.0-bookworm AS go-toolchainFROM node:24.14.1-bookworm AS node-toolchainFROM hexpm/elixir:1.20.4-erlang-29.1.2-debian-bookworm-20261005 AS elixir-toolchain
FROM python:3.14.5-bookworm
ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 \ PATH=/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ VIPS_RUNNER=1 \ VIX_COMPILATION_MODE=PLATFORM_PROVIDED_LIBVIPS \ GOCACHE=/tmp/vips-handbook-go-cache \ GOPROXY=https://proxy.golang.org,direct \ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \ COREPACK_ENABLE_DOWNLOAD_PROMPT=0
RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ ca-certificates \ cmake \ fontconfig \ fonts-dejavu-core \ git \ libarchive-dev \ libcairo2-dev \ libcgif-dev \ libexif-dev \ libexpat1-dev \ libfftw3-dev \ libfontconfig1-dev \ libglib2.0-dev \ libheif-dev \ libimagequant-dev \ libjpeg62-turbo-dev \ liblcms2-dev \ libopenjp2-7-dev \ libpango1.0-dev \ libpng-dev \ libsctp1 \ librsvg2-dev \ libspng-dev \ libtiff-dev \ libwebp-dev \ meson \ ninja-build \ pkg-config \ time \ xz-utils \ zlib1g-dev \ && rm -rf /var/lib/apt/lists/*
COPY --from=go-toolchain /usr/local/go /usr/local/go
COPY --from=node-toolchain /usr/local/bin/node /usr/local/bin/nodeCOPY --from=node-toolchain /usr/local/lib/node_modules /usr/local/lib/node_modulesRUN ln -sfn ../lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ && ln -sfn ../lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \ && ln -sfn ../lib/node_modules/corepack/dist/corepack.js /usr/local/bin/corepack \ && corepack enable \ && corepack prepare pnpm@12.11.2 --activate
COPY --from=elixir-toolchain /usr/local/lib/erlang /usr/local/lib/erlangCOPY --from=elixir-toolchain /usr/local/lib/elixir /usr/local/lib/elixirRUN ln -sfn ../lib/erlang/bin/erl /usr/local/bin/erl \ && ln -sfn ../lib/erlang/bin/erlc /usr/local/bin/erlc \ && ln -sfn ../lib/erlang/bin/escript /usr/local/bin/escript \ && ln -sfn ../lib/erlang/bin/epmd /usr/local/bin/epmd \ && ln -sfn ../lib/elixir/bin/elixir /usr/local/bin/elixir \ && ln -sfn ../lib/elixir/bin/elixirc /usr/local/bin/elixirc \ && ln -sfn ../lib/elixir/bin/iex /usr/local/bin/iex \ && ln -sfn ../lib/elixir/bin/mix /usr/local/bin/mix
# libvips 8.17.3 is built in-image so `vips --version` matches the lock file.# ImageMagick, OpenSlide, FITS, NIfTI, and JPEG XL are left out: current recipes# use JPEG, PNG, WebP, TIFF, and SVG, and a distro Magick loader would change# foreign-loader priority. HEIF stays enabled so a missing AVIF/HEIF loader is# visible in `vips -l foreign` rather than failing silently later.ARG LIBVIPS_VERSION=8.17.3ARG LIBVIPS_SHA256=41e9a1439cd57dcc6d4435a085e2cfe181d9da1962fa84a484f09e8b536e4b77ADD --checksum=sha256:${LIBVIPS_SHA256} \ https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.xz \ /tmp/vips.tar.xz
RUN tar -xJf /tmp/vips.tar.xz -C /tmp \ && cd /tmp/vips-${LIBVIPS_VERSION} \ && meson setup build \ --prefix=/usr/local \ --libdir=lib \ --buildtype=release \ -Ddeprecated=false \ -Dexamples=false \ -Dintrospection=disabled \ -Dmodules=disabled \ -Dmagick=disabled \ -Dmagick-module=disabled \ -Dcfitsio=disabled \ -Dmatio=disabled \ -Dnifti=disabled \ -Dopenexr=disabled \ -Dopenslide=disabled \ -Dopenslide-module=disabled \ -Dpdfium=disabled \ -Dpoppler=disabled \ -Dpoppler-module=disabled \ -Djpeg-xl=disabled \ -Djpeg-xl-module=disabled \ -Dquantizr=disabled \ -Dhighway=disabled \ -Djpeg=enabled \ -Dpng=enabled \ -Dwebp=enabled \ -Dtiff=enabled \ -Dexif=enabled \ -Dlcms=enabled \ -Dfftw=enabled \ -Dfontconfig=enabled \ -Dpangocairo=enabled \ -Drsvg=enabled \ -Dheif=enabled \ -Dheif-module=disabled \ -Dcgif=enabled \ -Dspng=enabled \ -Dopenjpeg=enabled \ -Dimagequant=enabled \ -Darchive=enabled \ -Dzlib=enabled \ -Dnsgif=true \ && meson compile -C build \ && meson install -C build \ && echo /usr/local/lib > /etc/ld.so.conf.d/usr-local.conf \ && ldconfig \ && fc-cache -f \ && mkdir -p /opt/vips-handbook \ && vips -l foreign > /opt/vips-handbook/foreign-loaders.txt \ && grep -q 'jpegload' /opt/vips-handbook/foreign-loaders.txt \ && grep -q 'webpload' /opt/vips-handbook/foreign-loaders.txt \ && grep -q 'pngload' /opt/vips-handbook/foreign-loaders.txt \ && grep -q 'svgload' /opt/vips-handbook/foreign-loaders.txt \ && grep -q 'heifload' /opt/vips-handbook/foreign-loaders.txt \ && rm -rf /tmp/vips-${LIBVIPS_VERSION} /tmp/vips.tar.xz
RUN pip install --no-cache-dir 'pyvips==3.2.0' \ && python3 -c "import pyvips; v='.'.join(str(pyvips.version(i)) for i in range(3)); assert pyvips.__version__=='3.2.0', pyvips.__version__; assert v=='8.17.3', v" \ && test "${VIX_COMPILATION_MODE}" = "PLATFORM_PROVIDED_LIBVIPS" \ && test -z "${VIPS_BLOCK_UNTRUSTED:-}" \ && vips --version | grep -qx 'vips-8.17.3'
WORKDIR /workCMD ["pnpm", "--version"]Related pages
Section titled “Related pages”- Install and verify
- Version compatibility matrix
- libvips 8.17.3 release, reviewed 2026-10-17