Skip to content
Latchkey

How to Speed Up Docker Builds in CI

Docker builds are often the slowest part of CI. BuildKit caching and a few layer-ordering habits cut most of the time.

A cold Docker build reinstalls everything every run. The fix is to reuse layers across runs and only rebuild what actually changed.

1. Enable BuildKit with a registry cache

Use docker/build-push-action with cache-from and cache-to so unchanged layers are pulled instead of rebuilt.

.github/workflows/build.yml
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v6
  with:
    context: .
    push: true
    tags: myorg/app:${{ github.sha }}
    cache-from: type=registry,ref=myorg/app:buildcache
    cache-to: type=registry,ref=myorg/app:buildcache,mode=max

2. Order layers cheap-to-expensive

Copy package manifests and install dependencies before copying source. Source changes every commit; dependencies rarely do, so a stable dependency layer stays cached.

3. Use multi-stage builds

Build in a fat stage, copy only artifacts into a slim final stage. Less to push, less to pull next run.

4. Skip the build when nothing changed

Add path filters so image builds run only when the Dockerfile or app source changes, not on every docs edit.

Key takeaways

  • Registry-backed BuildKit cache is the biggest win.
  • Order Dockerfile layers so dependencies stay cached.
  • Multi-stage builds shrink push and pull time.

Related guides

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