Skip to content

Question: GHCR image cleanup strategy for ephemeral tags and orphan architecture-specific layers #32

@thpham

Description

@thpham

Hi 👋

First, thanks for this excellent workflow example! The native multi-arch build approach (avoiding QEMU) is exactly what we're looking for in our CI/CD pipelines.

Context

We're adopting this workflow pattern for building ephemeral images (e.g., per-PR preview images, feature branch builds, or short-lived testing images). In these scenarios, we frequently create and delete image tags.

Question / Feature Request

I'm wondering if you've thought about or have recommendations for GHCR image cleanup strategies, particularly around:

1. Cleanup of ephemeral tags

When building images for PRs or feature branches, we end up with many tags like:

  • ghcr.io/org/repo:pr-123
  • ghcr.io/org/repo:feature-xyz
  • ghcr.io/org/repo:sha-abc1234

These accumulate quickly and contribute to GitHub storage quota consumption.

2. Orphan architecture-specific layers

This is the trickier part. With the push-by-digest approach used in the build job, each architecture (amd64, arm64) pushes its layers independently before the manifest merge. When an ephemeral tag is deleted:

  • Does deleting the manifest list automatically dereference the underlying arch-specific image digests?
  • Are the architecture-specific layers (blobs) eventually garbage collected by GHCR?
  • Or do we need to explicitly clean up the individual @sha256:... references?

Our Concern

Without proper cleanup, our storage quota could explode with unused/orphan layers, especially since:

  • Each build produces 2x the layers (one per arch)
  • The per-arch images are pushed by digest before being referenced by the manifest
  • If only the tag/manifest is deleted, the underlying blobs might remain indefinitely

Would Love to Know

  • Have you considered adding a cleanup job to the workflow (perhaps triggered on PR close or on a schedule)?
  • Any experience or insights into how GHCR handles garbage collection of unreferenced blobs?
  • Would you consider adding documentation or an example for this use case?

Some options I've seen include:

Any guidance or best practices you could share would be greatly appreciated!

Thanks again for the great work on this repo 🙏

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationquestionFurther information is requested

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions