Skip to content

ci(docker): switch to registry-backed BuildKit cache (GHCR)#140

Merged
georgeh0 merged 1 commit intomainfrom
g/docker-registry-cache
Apr 15, 2026
Merged

ci(docker): switch to registry-backed BuildKit cache (GHCR)#140
georgeh0 merged 1 commit intomainfrom
g/docker-registry-cache

Conversation

@georgeh0
Copy link
Copy Markdown
Member

Follow-up to #138 / #139. The previous type=gha BuildKit cache is scoped per Git ref, so each release tag (v0.2.24, v0.2.25, …) creates a fresh cache scope and gets no reuse from earlier releases. Combined with GHA's 10 GB per-repo cache limit (which we already hit at ~10 GB before the v0.2.26 release), the cache effectively never helped consecutive releases — observed empirically: the v0.2.26 release re-installed sentence-transformers from scratch despite earlier runs having exported cache.

Summary

  • Switch to type=registry cache stored as buildcache-<variant> tags on the same GHCR package — branch/tag-independent, no LRU eviction, no size cap. Standard pattern for buildx multi-arch + multi-registry publishes.
  • Per-variant cache tag (buildcache-slim, buildcache-full) so the two image variants don't evict each other's cache layers.
  • mode=max continues to export intermediate layers (needed so the heavy stage 1 RUN uv pip install sentence-transformers layer is cached and reused).

Operational impact

  • Two extra tags will appear under the cocoindex-io/cocoindex-code GHCR package — :buildcache-slim, :buildcache-full. They aren't intended for docker pull; safe to mark as private or simply ignore in package listing.
  • I've already cleaned up 23 orphaned GHA cache entries on the deleted g/docker-layer-cache-v2 branch (~3.4 GB freed). Remaining v0.2.26-scoped GHA caches will age out naturally (7-day TTL, or when GHA evicts them under pressure).

Test plan

  • A workflow_dispatch with test_docker=true after this lands will populate the :buildcache-* tags.
  • The next real release (or another dispatch) should hit cache — Build & push step should be dramatically shorter than the v0.2.26 cold run (~10 min → ~2 min hopefully, since the heavy ST install layer reuses).

🤖 Generated with Claude Code

The previous `type=gha` cache was scoped per Git ref, so each release
tag created a new cache scope and never reused a previous release's
layers. Add to that GHA's 10 GB per-repo limit (which we already hit at
~10 GB before the v0.2.26 release), and the cache effectively never
helped consecutive releases.

Move to `type=registry` cache stored as separate `buildcache-<variant>`
tags on the same GHCR package. Branch/tag-independent, no LRU eviction,
unlimited size for our purposes. Standard pattern for multi-arch
buildx + multi-registry publishes.

Per-variant cache tag (`buildcache-slim`, `buildcache-full`) so the two
variants don't evict each other's layers.

`mode=max` exports all intermediate layers, not just the final ones —
needed for the per-RUN-layer reuse strategy in the Dockerfile.

Also cleaned up 23 orphaned GHA cache entries on the deleted
g/docker-layer-cache-v2 branch (3.4 GB freed).
@georgeh0 georgeh0 merged commit 90d8ff9 into main Apr 15, 2026
9 of 10 checks passed
@georgeh0 georgeh0 deleted the g/docker-registry-cache branch April 15, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant