Cache is King: A guide for Docker layer caching in GitHub Actions
Pain points with Docker layer caching in GitHub Actions
- Many report that network transfer time for cache save/restore often cancels out build-time gains.
- Registry-based caches (including “registry mirror” or OCI-based caches) frequently end up no faster than rebuilding, especially for intermediate layers.
- Only successful builds typically get cached, reducing usefulness for failing or experimental branches.
Local disks, self‑hosted runners, and “sticky disks”
- Strong consensus that fast, local, persistent storage (NVMe, large disks) is the only consistently effective way to speed Docker builds.
- “Sticky disks” between runs can dramatically reduce repeated downloads/compiles, but require idempotent steps and careful cleanup.
- Self-hosted or Kubernetes-based runners with big local disks are seen as the pragmatic solution, though they add infra complexity and isolation concerns in multi-tenant environments.
Third‑party and alternative tools
- Several services aim to provide faster runners and colocated cache, or persistent BuildKit state.
- Some use external runners that support custom images and S3-based caches.
- Others use separate build systems (e.g., Jenkins) mainly to get on-disk Docker layer reuse.
Build system design and alternatives to Dockerfile
- Some argue the best “solution” is not to use
docker buildat all: use Bazel + OCI rules, Gradle Jib, or Nix-based image builders for more granular, reliable caching. - There is pushback that tools like Bazel and Nix are complex, risky without multiple in-house experts, and can become serious tech debt if “the expert” leaves.
- Several advocate building artifacts outside Docker and then copying them into minimal images.
GitHub Actions and platform incentives
- GitHub Actions is praised for easy entry but criticized as hard to scale and awkward to configure for advanced needs (like robust caching).
- Some suggest GitHub has little incentive to make builds faster since billing is per-minute and focus has shifted toward AI features.
- Comparisons note other CI systems (GitLab, Bitbucket, CircleCI, Jenkins) having more mature or simpler caching and runner models.
Technical tips, optimizations, and skepticism
- Tips: use multiple
cache-from/cache-toendpoints; prefer local GHA cache; use BuildKit options likeimage-manifest=truewhen caching to the same registry; use cache mounts (RUN --mount type=cache). - Shrinking image size (removing unused toolchains, libraries) can meaningfully speed builds and pulls.
- Some contributors conclude that, beyond select cases (e.g., Node builds), complex caching setups are often not worth the engineering effort relative to simpler, uncached builds or better hardware.