如何检查具有特定标记的 Docker 映像是否在本地存在?

我想知道一个带有特定标记的 Docker 映像是否存在于本地。如果 Docker 客户端不能本地执行这些操作,那么使用 bash 脚本就可以了。

为了给可能的 bash 脚本提供一些提示,运行 docker images命令的结果返回以下内容:

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
166010 次浏览

我通常测试 docker images -q的结果(如在 这个剧本中) :

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

但是 因为 ABC0只接受 ABC1作为参数,所以需要在标记上进行 grep,而不使用 -q

现在接受标签(docker 1.8 +) [REPOSITORY[:TAG]]

下面提到的另一种方法是使用 码头检查
但对于 docker 17 + ,图像的语法是: < a href = “ https://docs.docker.com/engine/reference/commandline/image _ sight/”rel = “ noReferrer”> docker image inspect (对于一个不存在的图像,即 退出状态将为非0)

正如 伊塔布评论中指出的:

  • 在有大量图像的机器上,docker images -q方法会变得非常慢。在一台6500张图像的机器上运行需要44个镜头。
  • docker image inspect立即返回。

正如 亨利 · 布莱斯的评论所指出的:

如果使用 docker image inspect my_image:my_tag,并且希望忽略输出,那么可以添加 --format="ignore me",它将逐字打印输出。

您还可以通过添加 >/dev/null来重定向 stdout,但是,如果您不能在脚本中这样做,那么 format 选项就可以正常工作。

在上面的 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

将其用于现有的图像和标记将打印 exists,例如:

./check.sh rabbitmq:3.4.4

将其用于不存在的图像和标记将打印 doesn't exist,例如:

./check.sh rabbitmq:3.4.3

例如,试试 docker inspect:

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

但是现在有了一个已经存在的图像,你就会得到一大堆信息,例如:

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

这是一个不错的 json 格式。

你可以像下面这样使用:

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

或者:

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

第三季:

docker image inspect myimage:mytag

作为示范..。

返回文章页面成功译者:

$ 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

失败,缺失的形象:

$ 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

参考文献:

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

使用 test

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

或者排成一行

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

如果您试图从一个 Docker 注册表中搜索一个 Docker 映像,我想检查是否存在一个 Docker 映像的最简单的方法是使用 Docker V2 REST API < em > Tags 列表服务

例子:-

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

如果上面的结果返回200Ok 并带有一系列图像标记,那么我们就知道图像存在

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

如果你看到

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

那你肯定知道那画面根本不存在。

这只是我对优秀读者的一点心意:

建造

#!/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

看好了

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

快跑

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

用于特定的标记名

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

对于“ like 子句”标签名: my _ image _ tag —— > start my _ ima *

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

如果你想要一些“图像”例如删除所有的图像标签开始“我 _ ima”尝试这一点

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

在 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

上面的示例脚本检查带有5.6标记的 mysql 图像是否存在。如果你只是想检查一下是否存在没有特定版本的 mysql 映像,那么就像下面这样传递没有标记的存储库名称:

IMAGE_NAME="mysql"

我认为这个功能应该在 docker build命令中实现(使用标志?)这样就避免了大量的代码复制。

我在一个名为 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 "$@"
}

免责声明 : 这还不能用于生产,因为它只适用于长格式的空格分隔参数,即 --tag hello-world:latest。此外,这只是修改 docker build命令,所有其他命令保持不变。如果有人有进步,请告诉我。

我之所以想分享这个片段,是因为在 bash 函数中包装标准命令以避免代码重复的想法似乎比编写包装器语句更加优雅和可伸缩。

受@rubicks 上面回复的启发。

检查图像是否已经存在

image_name_tag="alpine:3.13.3"


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

如果图像不存在就拉

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

演示执行

# 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}
$

我喜欢这个,因为它简洁明了,语义也恰当。如果图像真的存在,还有什么比这更容易的呢?

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