Clean up stale Docker Hub tags with a review-first workbench
See which repositories are hoarding old tags, let an agent draft a keep-versus-delete plan, then approve it yourself before anything is removed.
I want an app for cleaning up our Docker Hub registry. Every CI run pushes another tag and nobody ever deletes them, so our storage keeps climbing, and the Docker Hub website gives me no way to review and bulk-remove old tags. The guiding rule for the whole app: nothing is ever deleted automatically. A human reviews and approves every deletion. Docker Hub is the only integration involved.
Home view, the repository overview. The app opens on a list of every repository in our namespace, loaded with List Repositories in a Namespace, enriched per repository with Get Repository for pull count, star count and last-updated date. Let me set the namespace in a settings field, since it is our Docker ID for personal repositories and our organization name for org-owned ones. Show one row per repository with: repository name, tag count, total pull count, when it was last updated, and a staleness indicator showing how long it has been since anything was pushed. Make the columns sortable and default the sort to the biggest bloat first, meaning the most tags combined with the longest time since an update. Each row links into the tag workbench and carries a "Draft a cleanup plan" button.
Repository view, the tag workbench. Clicking a repository pulls the full tag list with List Repository Tags, paginating all the way through rather than showing only the first page, and using Read Repository Tag when I open a single tag for detail. Docker Hub tag objects expose last_updated, tag_last_pushed and tag_last_pulled as ISO 8601 UTC timestamps, so build the age columns and every staleness filter on those fields and render them as friendly relative ages like "pushed 8 months ago" with the exact timestamp on hover. Show a table of tag name, image size, digest, last pushed, last pulled and a computed age. Let me sort by last pushed and by last pulled in both directions.
Filters on the workbench. Give me quick filters I can toggle: "not pulled in 90 days" with the day count editable, "commit SHA style tags" matching tags that look like git hashes, "keep anything that looks like a semantic version" which excludes version-number tags from the current selection, and a free-text name search. Filters should combine, and the header should always tell me how many tags match and how many are currently selected.
Protected tags. Each repository has a protected list stored in the app, seeded with latest and anything I add such as our current release tags. Protected tags render with a lock marker, their checkbox is disabled, and no filter or bulk-select action can ever select them. I manage that list from the same screen.
Deleting. I pick tags with checkboxes, with a select-all that respects the active filters and skips protected tags, then press Delete Selected. That opens a confirmation dialog that spells out exactly what is about to go: the full list of tag names with their last pushed and last pulled dates, the count, and a warning that deletion is permanent. Only after I confirm does the app run Delete Repository Tag for each selected tag, checking each one first with Check Repository Tag so a tag that has already disappeared is skipped rather than erroring. Show progress while it works, then a result summary of what was deleted and what failed, and refresh the tag list. Keep a deletion history for the repository showing what was removed and when.
Locking important tags. From the same screen I can lock a repository's important tags using Update Repository Immutable Tags, entering or picking the rule that covers the tags that must never change. Validate the rule with Verify Repository Immutable Tag Rule before saving it and show me which existing tags the rule would cover, so I can see the effect before committing.
The cleanup plan agent. Every repository has a "Draft a cleanup plan" button that kicks off a background agent. The agent reads every tag in that repository with List Repository Tags and Read Repository Tag, classifies each tag as a release, a CI build or a one-off, then reasons about what is safe to remove given the retention rules and the protected list. It writes a proposed keep-versus-delete list back into the app, one row per tag with the classification, the recommendation and a short plain-English reason such as "CI build from March, never pulled, superseded by 47 later builds". While it runs, show the repository as having a plan in progress; when it lands, show the plan as a reviewable panel next to the tag table.
Reviewing the plan. I approve or edit the plan before anything is deleted. Let me flip any row from delete to keep or the other way round, and accept the whole plan at once. Approving a plan does nothing more than tick the matching checkboxes in the workbench, so the deletion still goes through the same confirmation dialog. The agent never deletes anything itself and never calls Delete Repository Tag. Store plans per repository with their status and the time they were generated, so I can come back to a plan later or regenerate it.
Constraints to respect. Do not build any UI for editing repository descriptions or privacy settings, because those edits are not possible with token authentication and will fail. Tag lists can run into the thousands, so paginate the reads, cache them per repository within the session, and give me a refresh control instead of refetching everything on every interaction. Handle rate limiting gracefully by backing off and retrying rather than failing the whole screen.
What does this prompt do?
- Opens on every repository in your namespace with tag counts, pull counts and how long it has been since anything was pushed, so you can see at a glance where the storage is going.
- Click into a repository for a tag workbench sorted by last pushed and last pulled, with one-click filters for tags nobody has pulled in 90 days, commit-hash build tags, and version numbers worth keeping.
- Hit "Draft a cleanup plan" and a background agent reads every tag, separates real releases from throwaway CI builds, and writes back a keep-versus-delete list with a one-line reason for each tag.
- Tick the tags you agree with, confirm the exact list in a dialog that spells out what is about to go, and only then are they deleted. You can also lock the tags your deploys depend on so they cannot be picked at all.
What do I need to use this?
- A Docker Hub account connected with permission to delete tags
- The namespace you want to clean up, which is your Docker ID for personal repositories or your organization name for shared ones
- A rough sense of your retention rules, such as which tags are untouchable and how stale is too stale
How can I customize it?
- Change the staleness threshold from 90 days to whatever matches your release cadence
- Edit the protected list per repository so the tags your deployments depend on can never be selected for deletion
- Adjust the retention rules the agent reasons about, for example keeping the last five builds per branch or every version number ever released
FAQs
Will this delete any tags on its own?
Can I recover a tag after it is deleted?
Does this work for organization repositories or only personal ones?
How does it decide which tags are safe to remove?
How do I stop someone deleting an important tag by mistake?
Related templates
See who and what can reach your Docker Hub organization, spot the stale and never-used credentials, and shut them off without leaving the page.
A board that lines up the versions you tagged against the images your registry actually has, so a quiet build failure never reaches a customer.
On the first working day of each month, compare who can reach your Docker Hub organization with your active staff list and post the gaps to Slack.
Every weekday morning, get a clean Slack summary of which Docker Hub images picked up new tags in the last day, grouped by repository.
Every morning we scan your Docker Hub activity for risky changes and post a plain-English alert to Slack, staying quiet when nothing needs your attention.
Every Monday, get a short written rundown of how your public Docker images are doing, ranked by pulls with stars and fresh releases called out.
Stop letting CI tags pile up in Docker Hub.
Review what an agent proposes on one screen, then clear out months of clutter without risking a tag you still need.