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 jpegduring the build.zlib (PNG/ZIP) support not availablewarning, 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.
# 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 PillowCache & 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.
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-pillow-${{ hashFiles('requirements*.txt') }}Common errors
| Error | Cause | Fix |
|---|---|---|
| headers or library files could not be found for jpeg | libjpeg headers missing | apt-get install libjpeg-dev |
| zlib support not available | zlib headers missing | apt-get install zlib1g-dev |
| cannot open .ttf / freetype error | freetype missing | apt-get install libfreetype6-dev |
| No matching distribution (new Python) | No wheel yet | Pin 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.