Repository navigation
feat(pruner): keep images and containers of other workloads - #40
Merged
Merged
Conversation
DOCKER_PRUNE_KEEP_LABELS and DOCKER_PRUNE_KEEP_IMAGES protect images and stopped containers from the docker prune, in the normal and the low-space pass. Each full pass logs what it kept, with sizes. With either set, the pruner selects what to remove itself instead of calling docker system prune: that call has no reference filter, and with several label!= filters it spares only what carries all of them (containers on every image store, images on overlay2). Both empty keeps today's exact call. tests/pruner-docker.sh runs this on throwaway docker:dind daemons, one per image store. Closes #39 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PRUNE_FREE_PCT now defaults to 5 instead of 15, so the hourly low-space pass with its 2h age limit starts only when a disk is nearly full. Hosts that set PRUNE_FREE_PCT in .env are unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Image age now comes from docker image ls --filter until=, not .Created: containerd counts from arrival on the host, so the keep path was removing freshly pulled images the plain prune would hold. This needs Docker 25+ when a keep setting is on; an older daemon logs that and skips the docker prune. All listings now run before any removal, one container inspect replaces two, and docker_logged replaces the repeated log and sed pairs. The test pins the difference between the stores with a save and load fixture. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #39
What changes
DOCKER_PRUNE_KEEP_LABELSkeeps images and stopped containers carrying any listedkeyorkey=value, plus the image a kept container uses.DOCKER_PRUNE_KEEP_IMAGESkeeps images by name pattern (variscite:* ghcr.io/acme/*), for images you cannot label.*crosses/, and a bare repository covers all its tags.docker system prunecall as today.PRUNE_FREE_PCTnow defaults to5instead of15(separate commit).Please review: two departures from the issue
1. Labels do not map to
label!=filters. The issue asks for that, but it silently loses protection once two labels are set. Given severallabel!=filters, the daemon spares only what carries all of them. Measured on Docker 29.9.3:So with a keep setting active, the pruner asks docker about one label at a time and removes the rest itself, without
-f. The reference patterns needed this path anyway. Everything is listed before anything is removed, and if any listing fails, the pass stops rather than treating "no list" as "nothing to keep". Networks and build cache are still pruned with the same age limit asdocker system prune.Image age comes from the daemon's own
docker image ls --filter until=list, because the stores count differently: overlay2 from the build, containerd from arrival on the host. Measured with an image built long ago and pulled just now: on containerd the real prune keeps it, while a check on.Createdwould have removed it.2. The threshold change was requested separately. The issue lists thresholds as out of scope, but the 5% default was asked for alongside this work. It is its own commit, so it can be reverted alone. With 5%, the low-space pass starts much later, and the free-space check still runs only hourly, so a fast-filling disk has less headroom.
Known limits
untilonimage ls, and 25 to 29 accept it. On an older daemon the pass logs this and skips the docker prune, so images are not reclaimed there while a keep setting is on. With both settings empty there is no such requirement.docker compose uprather thandocker start. This is noted in the README.Testing
tests/pruner-docker.shruns against throwawaydocker:29-dinddaemons, one per image store, and stops if it finds itself connected to any other daemon. It adds adocker:dindpull and two privileged containers to theShell scriptsCI job, and skips when no docker daemon is available.label!=mapping made it fail on both, and computing image age from.Createdmakes it fail on containerd.tests/passes inubuntu:24.04, andshellcheck -xis clean on CI's file list.docker compose configshows a quoted.envvalue reaching the pruner unquoted, with*intact.After merge
Beelink needs Docker 25+,
DOCKER_PRUNE_KEEP_IMAGES=variscite:*in its.envand the new image rolled out. Until then the Variscite image is still exposed to pruning. Any host that setsPRUNE_FREE_PCTin.envkeeps its own value.🤖 Generated with Claude Code