Skip to content
Latchkey

How to Install Pillow (PIL) in CI Without Build Failures

Pillow ships wheels with image codecs bundled, but on a platform without a wheel it compiles against libjpeg, zlib, and friends - and slim runners lack the headers.

Pillow (PIL fork) wraps several image codec libraries. On mainstream platforms pip downloads a wheel with those bundled and there is nothing to do. The pain appears on Alpine/musl or a new Python where pip builds from source and needs libjpeg, zlib, and optionally freetype/tiff headers.

Why it fails in CI

A Pillow source build looks for development headers for the codecs you use - at minimum libjpeg and zlib. On a slim or Alpine image those are missing, so the build fails or silently produces a Pillow that cannot open JPEG/PNG files.

  • The headers or library files could not be found for jpeg during the build.
  • zlib (PNG/ZIP) support not available warning, then runtime errors opening PNGs.
  • fatal error: Python.h: No such file or directory - Python headers missing.

Install it reliably

Prefer the wheel: use a glibc base image and a supported Python, and force-binary so a missing wheel fails loudly. If you must build, install the codec dev packages you need.

Terminal
# Prefer the wheel - codecs already bundled
pip install --only-binary=:all: Pillow

# Source build fallback (Debian/Ubuntu)
apt-get update && apt-get install -y \
  build-essential python3-dev \
  libjpeg-dev zlib1g-dev libfreetype6-dev libtiff5-dev libwebp-dev
pip install Pillow

Cache & speed

Wheel installs are instant. If you build, bake the codec dev packages into the image and cache ~/.cache/pip so a successful build is reused.

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: pip-pillow-${{ hashFiles('requirements*.txt') }}

Common errors

ErrorCauseFix
headers or library files could not be found for jpeglibjpeg headers missingapt-get install libjpeg-dev
zlib support not availablezlib headers missingapt-get install zlib1g-dev
cannot open .ttf / freetype errorfreetype missingapt-get install libfreetype6-dev
No matching distribution (new Python)No wheel yetPin a supported Python

Key takeaways

  • Use the wheel; codecs come bundled and no build is needed.
  • To build, install libjpeg-dev + zlib1g-dev (plus freetype/tiff/webp as needed).
  • Glibc base + a supported Python avoids the codec-header problem.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →