dangling=true doesn't prune any images, as we are not creating dangling images. Using --all should remove unused images, but it considers the Git SHA tag on the latest image to be unused (presumably because there are two tags, the SHA and latest and the running container is only considered to be using "latest"). As a result it deletes the tag, which means that we can't rollback to that SHA later. Its a bit more complicated to only remove images that are not referenced by any containers. First we find the tags we want to keep from the containers (running and stopped). Then we append the latest tag to that list. Then we get a full list of image tags and remove those tags from that list (using `grep -v -w`). Finally we pass the tags to `docker rmi`. That either deletes the tag if there are other references to the image or both the tag and the image if it is the only one.
32 lines
980 B
Ruby
32 lines
980 B
Ruby
require "active_support/duration"
|
|
require "active_support/core_ext/numeric/time"
|
|
|
|
class Mrsk::Commands::Prune < Mrsk::Commands::Base
|
|
def images
|
|
pipe \
|
|
docker(:image, :ls, *service_filter, "--format", "'{{.Repository}}:{{.Tag}}'"),
|
|
"grep -v -w \"#{active_image_list}\"",
|
|
"while read tag; do docker rmi $tag; done"
|
|
end
|
|
|
|
def containers(keep_last: 5)
|
|
pipe \
|
|
docker(:ps, "-q", "-a", *service_filter, *stopped_containers_filters),
|
|
"tail -n +#{keep_last + 1}",
|
|
"while read container_id; do docker rm $container_id; done"
|
|
end
|
|
|
|
private
|
|
def stopped_containers_filters
|
|
[ "created", "exited", "dead" ].flat_map { |status| ["--filter", "status=#{status}"] }
|
|
end
|
|
|
|
def active_image_list
|
|
"$(docker container ls -a --format '{{.Image}}\\|' --filter label=service=#{config.service} | tr -d '\\n')#{config.latest_image}"
|
|
end
|
|
|
|
def service_filter
|
|
[ "--filter", "label=service=#{config.service}" ]
|
|
end
|
|
end
|