如何通过标记删除 Docker 图像,最好使用通配符?

我有一些自动化的过程,喷涌出一堆 Docker 图像标记有意义的标签。这些标签遵循一种结构化的模式。

有没有一种通过标签来查找和删除图片的方法? 所以假设我有图片:

REPOSITORY                  TAG
junk/root                   stuff_687805
junk/root                   stuff_384962

理想情况下,我希望能够做: docker rmi-tag stuff _ *

有什么好的模拟方法吗?

72862 次浏览

Docker provides some filtering which you can use with labels, but I don't see wildcard support.

docker images -f "label=mylabel=myvalue"

Furthermore to add labels to an image you must add the information to the Dockerfile with a LABEL command. I couldn't find a way to add labels to an image unless you changed the Dockerfile (i.e. couldn't find a commandline option), though you can add them to containers at runtime with --label and --label-file (run docs).

Fun with bash:

docker rmi $(docker images | grep stuff_ | tr -s ' ' | cut -d ' ' -f 3)

You can also acomplish it using grep + args + xargs:

docker images | grep "stuff_" | awk '{print $1 ":" $2}' | xargs docker rmi
  • docker images lists all the images
  • grep selects the lines based on the search for "_stuff"
  • awk will print the first and second arguments of those lines (the image name and tag name) with a colon in between
  • xargs will run the command 'docker rmi' using every line returned by awk as it's argument

Note: be careful with the grep search, as it could also match on something besides the tag, so best do a dry run first:

docker images | grep "stuff_" | awk '{print $1 ":" $2}' | xargs -n1 echo
  • xargs -n1 the -n1 flags means xargs will not group the lines returned by awk together, but echo them out one at a time (for better readability)

Using only docker filtering:

 docker rmi $(docker images --filter=reference="*:stuff_*" -q)
  • reference="*:stuff_*" filter allows you to filter images using a wildcard;
  • -q option is for displaying only image IDs.

Update: Wildcards are matched like paths. That means if your image id is my-company/my-project/my-service:v123 then the * won't match it, but the */*/* will. See the github issue for description.

docker rmi $(docker images | grep stuff | tr -s ' ' | cut -d ' ' -f 3)

I would use the image id to remove the images, the tag being '1.2.3':

docker rmi $(docker images | awk '$2~/1.2.3/{print $3}')

only using docker

docker rmi $(docker images -q junk/root:*)

Done the Docker way:

docker rmi -f $(docker images -f=reference='<image_name>:<tag_name>*' --format "\{\{.ID}}")

Replace with your <image_name> and <tag_name>.

in docker version 20.10.20 linux I had to tell the path for the Repository with / as described in some comments, so here was my solution

Example of what I get when I do a docker image

as you can see I need something to select the TAG, lets say: delete everything related to feature 1

REPOSITORY                             TAG                        IMAGE ID       CREATED             SIZE
nexus-snapshot.bla.com/core/apple      6.6.1-feature_1-SNAPSHOT   82cb336f7ed1   2 months ago   1.11GB
nexus-snapshot.bla.com/core/orange     6.6.1-feature_1-SNAPSHOT   82cb336f7ed2   2 months ago   1.12GB
nexus-snapshot.bla.com/core/apple      6.6.1-feature_2-SNAPSHOT   82cb336f7ed3   8 hours ago   1.11GB
nexus-snapshot.bla.com/core/orange     6.6.1-feature_2-SNAPSHOT   82cb336f7ed4   8 hours ago   1.12GB
nexus-snapshot.bla.com/core/apple      6.6.1-feature_3-SNAPSHOT   82cb336f7ed5   1 hour ago   1.11GB
nexus-snapshot.bla.com/core/orange     6.6.1-feature_3-SNAPSHOT   82cb336f7ed6   1 hour ago   1.12GB

Solution:

$ docker rmi $(docker images --filter=reference="nexus*/*/*:6.6.1-feature_1*" -q) -f

Explanation:

note I will be using ... instead of * to make more human readable, it means any character

1 - Between the brackets () the inner command is:

searching for nexus.../.../... : tag 6.6.1-feature_1.... which than will return the id for 82cb336f7ed1 and 82cb336f7ed2

2 - The id will be passed to the outer command docker rmi {82cb336f7ed1, 82cb336f7ed2} -f to force remove the images