Как проверить, существует ли локально образ Docker с определенным тегом?

117

Я хотел бы узнать, существует ли локально образ Docker с определенным тегом. Я могу использовать bash-скрипт, если клиент Docker не может этого сделать изначально.

Просто чтобы дать некоторые подсказки для потенциального сценария 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
Johan
источник

Ответы:

160

Обычно я проверяю результат docker images -q(как в этом скрипте ):

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

Но поскольку docker imagesпринимает только REPOSITORYкак параметр, вам нужно будет использовать grep в теге без использования-q,

docker images теперь принимает теги (докер 1.8+) [REPOSITORY[:TAG]]

Другой подход, упомянутый ниже, - использовать docker inspect .
Но с docker 17+ синтаксис изображений таков: docker image inspect(на несуществующем изображении статус выхода будет отличным от 0 )

Как отмечает iTayb в комментариях :

  • Этот docker images -qметод может работать очень медленно на машине с большим количеством изображений. Для запуска на машине с 6500 изображениями требуется 44 секунды.
  • В docker image inspectвозвращается немедленно.
VonC
источник
1
Хм, не уверен, работает ли это для тегов? Когда я выполняю «docker images -q rabbitmq», он возвращает «e8e654c05c91 и a4fbaad9f996», но если я выполняю «docker images -q rabbitmq: 3.4.4», ничего не возвращается, даже если тег существует.
Йохан,
@Johan Даже если тег существует локально?
VonC
@Johan Я только что дважды проверил, и параметр docker images действительно принимает только репо, а не тег. Я отредактировал ответ, чтобы предложить альтернативное решение.
VonC
1
Спасибо, что похоже работает. Но, возможно, вам следует отредактировать свой ответ и удалить ": mytag" из "myimage: mytag", прежде чем я приму его?
Johan
для новичков: чем отличается изображение (myimage) от тега (mytag)? почему myimage: mytag, а не просто mytag?
Александр Миллс
37

Попробуйте 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.

Трэвис Ридер
источник
6
Это наиболее подходящий ответ.
Майкл Коул
2
Действительно, imagesи psкоманды всегда завершаются с 0, и inspectэто очень просто:docker inspect "${image_id}:${image_tag}" > /dev/null 2>&1 || echo "does not exist!"
Эрик Данненберг
docker inspectотлично из-за ненулевого кода возврата, когда изображения не существует.
cowlinator 06
Тогда это тоже намного быстрее docker images -q.
iTayb
26

tldr:

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/

rubicks
источник
это было просто, быстро и совместимо с будущим. Я буду придерживаться этого решения.
MarAvFe,
17

Вы можете использовать следующее:

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

Или:

[ -z $(docker images -q someimage:sometag) ] || echo "already exists"
Луис Бьянчин
источник
6
Не работает, по крайней мере, на macOS, возвращаемое значение всегда 0.
Габор Чарди
1
Код правильный и работает в Linux. Единственное, что я бы добавил, это кавычки к команде подоболочки
Дрейкен
3

С помощью приведенного выше ответа Vonc я создал следующий сценарий bash с именем check.sh:

#!/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
Johan
источник
2

С помощью test

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

или в одну строку

test ! -z "$(docker images -q <name:tag>)" &&  echo exist
Алекс Монтойя
источник
2

Если вы пытаетесь найти образ докера в реестре докеров, я думаю, что самый простой способ проверить, присутствует ли образ докера, - это использовать службу списка тегов REST API Docker V2.

Пример:-

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"}}]} 

тогда вы точно знаете, что изображения не существует.

Абхишек Дж.
источник
2

В сценарии 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

Пример сценария выше проверяет, существует ли изображение mysql с тегом 5.6. Если вы хотите просто проверить, существует ли какое-либо изображение mysql без конкретной версии, просто передайте имя репозитория без тега следующим образом:

IMAGE_NAME="mysql"
Намик Гаджиев
источник
0

Немного от меня очень хорошим читателям:

Сложение

#!/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
Артур Мустафин
источник
0

для конкретного имени тега

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

для тега "Like clause": my_image_tag -> start my_ima *

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

если вы хотите что-то «изображение», например, удалить все изображения, тег начал «my_ima», попробуйте это

docker rmi -f $(docker images -q  --filter reference='myreponame:my_ima*')
вороной
источник