Every GitHub Actions run was rebuilding the Docker image from layer 1, even though nothing in the Dockerfile had changed. The cache-from flag was set but having zero effect — build times stayed at 4+ minutes every run.
Root cause:
I was using actions/cache to cache Docker layers manually, but this approach has a subtle bug: the cache key was tied to the branch name, so PRs from forks and new branches always missed. The real fix is using docker/build-push-action with GitHub Actions native cache (type=gha), which handles key management automatically and works across branches.
Fix:
Replace the manual cache setup with this workflow step:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: myrepo/myapp:latest
cache-from: type=gha
cache-to: type=gha,mode=maxThe mode=max on cache-to caches all intermediate layers, not just the final image. Without it you still get cache misses on early layers.
Remove any manual actions/cache steps for Docker — they conflict with type=gha.
After this change, unchanged builds dropped from 4 minutes to under 30 seconds.
Lesson: Use docker/build-push-action with cache-from: type=gha and cache-to: type=gha,mode=max — manual actions/cache for Docker layers is fragile and almost never works correctly.