How to Install node-canvas (canvas) in CI
node-canvas renders with Cairo and Pango. Without those system libraries installed, the native build fails before npm even links it.
The canvas package builds against Cairo, Pango, libjpeg, giflib, and librsvg. CI images rarely ship these dev headers, so the build aborts with a pkg-config error.
Why it fails in CI
- Missing Cairo/Pango dev headers →
Package cairo was not found in the pkg-config search path. - No prebuilt binary for your Node version/platform forces a source build.
- Slim or Alpine images lack the graphics libraries entirely.
Install it reliably
Install the system libraries node-canvas links against, then install the package. The library set differs slightly by distro.
Terminal
# Debian/Ubuntu
apt-get update && apt-get install -y \
build-essential libcairo2-dev libpango1.0-dev \
libjpeg-dev libgif-dev librsvg2-dev
# Alpine
apk add --no-cache build-base cairo-dev pango-dev jpeg-dev giflib-dev
npm ciCache & speed
Bake the system libraries into a custom runner image so they are not reinstalled every run. Cache ~/.npm for the npm download; the compiled addon itself is fast once the libs are present.
.github/workflows/ci.yml
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}Common errors
Package cairo was not found/pango was not found→ install the-devpackages above.fatal error: jpeglib.h: No such file or directory→ installlibjpeg-dev.error: command 'gcc' failed→ installbuild-essential/build-base.
Key takeaways
- node-canvas needs Cairo, Pango, libjpeg, and friends as system dev packages.
- GitHub-hosted Ubuntu has most; containers and Alpine do not.
- Bake the libraries into a custom image to avoid reinstalling each run.
Related guides
How to Provide libvips for Node Image Builds in CIProvide libvips reliably in CI for sharp and image tooling: use the bundled libvips, install the system libra…
How to Make node-gyp Builds Work in CIFix node-gyp build failures in CI: install Python and a C/C++ toolchain, and stop "gyp ERR! find Python" and…
Self-Healing CI: Missing System Packages and Setup GapsA missing system library or tool fails the build until someone installs it. See the manual fix and how self-h…
Self-Healing CI: Auto-Retrying Transient Registry and 5xx FailuresRegistry timeouts, 429s, and 5xx errors are transient by definition. See why they happen and how self-healing…