简体   繁体   English

如何检查本地是否存在带有特定标签的 Docker 镜像?

[英]How to check if a Docker image with a specific tag exist locally?

I'd like to find out if a Docker image with a specific tag exists locally.我想知道本地是否存在带有特定标签的 Docker 映像。 I'm fine by using a bash script if the Docker client cannot do this natively.如果 Docker 客户端无法本地执行此操作,我可以使用 bash 脚本。

Just to provide some hints for a potential bash script the result of running the docker images<\/code> command returns the following:只是为了为潜在的 bash 脚本提供一些提示,运行docker images<\/code>命令的结果返回以下内容:

REPOSITORY                               TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
rabbitmq                                 latest              e8e654c05c91        5 weeks ago         143.5 MB
busybox                                  latest              8c2e06607696        6 weeks ago         2.433 MB
rabbitmq                                 3.4.4               a4fbaad9f996        11 weeks ago        131.5 MB

I usually test the result of docker images -q (as in this script ):我通常测试docker images -q的结果(如本脚本中所示):

if [[ "$(docker images -q myimage:mytag 2> /dev/null)" == "" ]]; then
  # do something
fi

Butsince docker images only takes REPOSITORY as parameter, you would need to grep on tag, without using -q由于docker images仅将REPOSITORY作为参数,因此您需要在标签上进行 grep,而不使用-q . .

docker images takes tags now (docker 1.8+) [REPOSITORY[:TAG]] docker images现在需要标签 (docker 1.8+) [REPOSITORY[:TAG]]

The other approach mentioned below is to use docker inspect .下面提到的另一种方法是使用docker inspect
But with docker 17+, the syntax for images is: docker image inspect (on an non-existent image, the exit status will be non-0 )但是对于 docker 17+,图像的语法是: docker image inspect (在不存在的图像上,退出状态将为 non-0

As noted by iTayb in the comments :正如iTayb评论中所指出的:

  • The docker images -q method can get really slow on a machine with lots of images. docker images -q方法在拥有大量图像的机器上会变得非常慢。 It takes 44s to run on a 6,500 images machine.在 6,500 张图像的机器上运行需要 44 秒。
  • The docker image inspect returns immediately. docker image inspect立即返回。

As noted in the comments by Henry Blyth :正如亨利·布莱斯( Henry Blyth)在评论中所指出的:

If you use docker image inspect my_image:my_tag , and you want to ignore the output, you can add --format="ignore me" and it will print that literally.如果您使用docker image inspect my_image:my_tag ,并且您想忽略输出,您可以添加--format="ignore me"并且它会逐字打印。

You can also redirect stdout by adding >/dev/null but, if you can't do that in your script, then the format option works cleanly.您还可以通过添加>/dev/null来重定向标准输出,但是,如果您不能在脚本中执行此操作,则格式选项可以正常工作。

Try docker inspect , for example:尝试docker inspect ,例如:

$ docker inspect --type=image treeder/hello.rb:nada
Error: No such image: treeder/hello.rb:nada
[]

But now with an image that exists, you'll get a bunch of information, eg:但是现在有了存在的图像,您将获得一堆信息,例如:

$ docker inspect --type=image treeder/hello.rb:latest
[
{
    "Id": "85c5116a2835521de2c52f10ab5dda0ff002a4a12aa476c141aace9bc67f43ad",
    "Parent": "ecf63f5eb5e89e5974875da3998d72abc0d3d0e4ae2354887fffba037b356ad5",
    "Comment": "",
    "Created": "2015-09-23T22:06:38.86684783Z",
    ...
}
]

And it's in a nice json format.它是一个很好的 json 格式。

tldr:域名:

docker image inspect myimage:mytag

By way of demonstration...通过示范...

success, found image:成功,找到图片:

$ docker image pull busybox:latest
latest: Pulling from library/busybox
Digest: sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f
Status: Image is up to date for busybox:latest

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
yes

failure, missing image:失败,缺少图像:

$ docker image rm busybox:latest
Untagged: busybox:latest
Untagged: busybox@sha256:32f093055929dbc23dec4d03e09dfe971f5973a9ca5cf059cbfb644c206aa83f

$ docker image inspect busybox:latest >/dev/null 2>&1 && echo yes || echo no
no

Reference:参考:

https://docs.docker.com/engine/reference/commandline/image_inspect/ https://docs.docker.com/engine/reference/commandline/image_inspect/

You can use like the following:您可以像下面这样使用:

[ -n "$(docker images -q someimage:sometag)" ] || echo "does not exist"

Or:或者:

[ -z "$(docker images -q someimage:sometag)" ] || echo "already exists"

With the help of Vonc's answer above I created the following bash script named check.sh :在上面Vonc 的回答的帮助下,我创建了以下名为check.sh bash 脚本:

#!/bin/bash
image_and_tag="$1"
image_and_tag_array=(${image_and_tag//:/ })
if [[ "$(docker images ${image_and_tag_array[0]} | grep ${image_and_tag_array[1]} 2> /dev/null)" != "" ]]; then
  echo "exists"
else
  echo "doesn't exist"
fi

Using it for an existing image and tag will print exists , for example:将它用于现有图像和标签将打印exists ,例如:

./check.sh rabbitmq:3.4.4

Using it for a non-existing image and tag will print doesn't exist , for example:将它用于不存在的图像和标签将打印doesn't exist ,例如:

./check.sh rabbitmq:3.4.3

In case you are trying to search for a docker image from a docker registry, I guess the easiest way to check if a docker image is present is by using the Docker V2 REST API Tags list service如果您尝试从 docker 注册表中搜索 docker 镜像,我想检查 docker 镜像是否存在的最简单方法是使用Docker V2 REST API标签列表服务

Example:-例子:-

curl $CURLOPTS -H "Authorization: Bearer $token" "https://hub.docker.com:4443/v2/your-repo-name/tags/list"

if the above result returns 200Ok with a list of image tags, then we know that image exists如果上面的结果返回 200Ok 和图像标签列表,那么我们知道图像存在

{"name":"your-repo-name","tags":["1.0.0.1533677221","1.0.0.1533740305","1.0.0.1535659921","1.0.0.1535665433","latest"]}

else if you see something like否则如果你看到类似的东西

{"errors":[{"code":"NAME_UNKNOWN","message":"repository name not known to registry","detail":{"name":"your-repo-name"}}]} 

then you know for sure that image doesn't exist.那么您肯定知道该图像不存在。

Using test使用test

if test ! -z "$(docker images -q <name:tag>)"; then
  echo "Exist"
fi

or in one line或在一行

test ! -z "$(docker images -q <name:tag>)" &&  echo exist

In bash script I do this to check if image exists by tag :在 bash 脚本中,我这样做是为了通过标签检查图像是否存在:

IMAGE_NAME="mysql:5.6"

if docker image ls -a "$IMAGE_NAME" | grep -Fq "$IMAGE_NAME" 1>/dev/null; then
echo "could found image $IMAGE_NAME..."
fi

Example script above checks if mysql image with 5.6 tag exists.上面的示例脚本检查是否存在带有 5.6 标记的​​ mysql 图像。 If you want just check if any mysql image exists without specific version then just pass repository name without tag as this :如果您只想检查是否存在没有特定版本的任何 mysql 映像,则只需传递不带标签的存储库名称,如下所示:

IMAGE_NAME="mysql"

Just a bit from me to very good readers:从我到非常好的读者的一点点:

Build建造

#!/bin/bash -e
docker build -t smpp-gateway smpp
(if  [ $(docker ps -a | grep smpp-gateway | cut -d " " -f1) ]; then \
  echo $(docker rm -f smpp-gateway); \
else \
  echo OK; \
fi;);
docker run --restart always -d --network="host" --name smpp-gateway smpp-gateway:latest

Watch手表

docker logs --tail 50 --follow --timestamps smpp-gateway

Run

sudo docker exec -it \
$(sudo docker ps | grep "smpp-gateway:latest" | cut -d " " -f1) \
/bin/bash

for specific tag name对于特定标签名称

$ docker images  --filter reference='<REPOSITORY>:TAG'

for "like clause" tagname:my_image_tag --> start my_ima*对于“like 子句”标记名:my_image_tag --> 启动 my_ima*

$ docker images  --filter reference='<REPOSITORY>:my_ima*'

if you want to someting "the image" for example delete all images tag started "my_ima" try this如果你想要一些“图像”,例如删除所有图像标签开始“my_ima”试试这个

docker rmi -f $(docker images -q  --filter reference='myreponame:my_ima*')

I think this functionality should be implemented inside the docker build command (using a flag?), so that it avoids a lot of code duplication.我认为这个功能应该在docker build命令中实现(使用标志?),这样它就可以避免大量的代码重复。

I used the same condition as the accepted answer inside a wrapper function called docker_build so that it does the necessary checks before calling the original docker build command.我在名为docker_build的包装函数中使用了与接受的答案相同的条件,以便它在调用原始docker build命令之前进行必要的检查。

# Usage: docker_build <...> (instead of docker build)

docker_build()
{
    local arguments=("$@")
    local index
    for (( index=0; index<$#; index++ )); do
        case ${arguments[index]} in
            --tag)
                local tag=${arguments[index+1]}
                if [[ ! -z $(docker images -q "${tag}" 2> /dev/null) ]]; then
                    echo "Image ${tag} already exists."
                    return
                fi
                ;;
        esac
    done
    command docker build "$@"
}

Disclaimer : This is not ready for production because it works only with space-separated arguments in long format ie --tag hello-world:latest .免责声明:这尚未准备好用于生产,因为它仅适用于长格式的空格分隔参数,即--tag hello-world:latest Also, this just modifies the docker build command only, all other commands remain same.此外,这仅修改docker build命令,所有其他命令保持不变。 If anyone has improvements, please let me know.如果有人有改进,请告诉我。

I felt like sharing this snippet because the idea of wrapping-standard-commands-in-bash-functions, to avoid code repetition, seemed more elegant and scalable than writing wrapper statements.我想分享这个片段,因为在 bash 函数中包装标准命令以避免代码重复的想法似乎比编写包装器语句更优雅和可扩展。

Inspired by @rubicks's response above.灵感来自@rubicks 上面的回复。

To check if the image exists already检查图像是否已经存在

image_name_tag="alpine:3.13.3"

docker image inspect ${image_name_tag} > /dev/null
echo $?

Pull if image does not exist如果图像不存在则拉取

docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}

Demo execution演示执行

# image_name_tag="alpine:3.13.3"
# 
# docker image inspect ${image_name_tag} > /dev/null
echo $?
Error: No such image: alpine:3.13.3
# echo $?
1
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
Error: No such image: alpine:3.13.3
3.13.3: Pulling from library/alpine
9aae54b2144e: Pull complete 
Digest: sha256:826f70e0ac33e99a72cf20fb0571245a8fee52d68cb26d8bc58e53bfa65dcdfa
Status: Downloaded newer image for alpine:3.13.3
docker.io/library/alpine:3.13.3
# docker image inspect ${image_name_tag} > /dev/null || docker  pull ${image_name_tag}
$ 

I like this because it is concise and has the proper semantics.我喜欢这个,因为它简洁并且具有正确的语义。 If the image exists it is true what could be easier?如果图像存在,那是真的,还有什么比这更容易的呢?

if [ $(docker image ls ${build_env} --format="true") ] ; 
then
 echo "does exist"
fi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM