7 hours ago
- Docker build caching involves three distinct caches: layer cache, mount cache, and image store, each with different lifetimes and invalidation rules.
- Layer caching is all-or-nothing within a stage; a change invalidates its layer and all subsequent layers in the chain.
- Mount caches (e.g., package manager caches) persist across builds and make re-runs faster by preserving state, but they are not exported with layer cache backends.
- Export backends (e.g., GHA, registry) help skip unchanged layers on fresh runners but can be slower than no cache if mount caches are critical, due to import/export overhead.
- Persistent state (keeping caches between jobs) significantly outperforms export backends in common scenarios like source changes and dependency updates.
- Layer ordering in Dockerfiles is crucial: place expensive and stable steps before frequently changing content to optimize caching.
- For compiled languages, mount cache survival is key; export backends cannot replicate this, making persistent builder state essential.
- Share caches based on image lineage (sets of builds that reuse layers), not just repo boundaries, for optimal efficiency.
- Caches grow with distinct dependency versions, not build count; some toolchains self-trim, others require manual key resets.
- Image store caching (e.g., shared /var/lib/docker) reduces pull times for common images, especially beneficial in fan-out patterns.
- Reproducible builds and tags are important to avoid defeating deduplication in shared image caches.
- The seven rules of thumb summarize key insights for optimizing Docker caching in CI, balancing layer ordering, mount caches, and distribution.