web-dev-qa-db-fra.com

Vérifier si la combinaison image: étiquette existe déjà sur le hub de docker

Dans le cadre d'un script bash, je souhaite vérifier si une combinaison image: étiquette particulière existe: En outre, ce sera un référentiel privé.

c'est-à-dire que le pseudocode serait comme:

tag = something
if image:tag already exists on docker hub:
    Do nothing
else
    Build and Push docker image with that tag
21
rgareth

S'il vous plaît, essayez celui-la

function docker_tag_exists() {
    curl --silent -f -lSL https://index.docker.io/v1/repositories/$1/tags/$2 > /dev/null
}

if docker_tag_exists library/nginx 1.7.5; then
    echo exist
else 
    echo not exists
fi

Mettre à jour:

En cas d'utilisation de Docker Registry v2 (basé sur this ):

# set username and password
UNAME="user"
UPASS="password"

function docker_tag_exists() {
    TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username": "'${UNAME}'", "password": "'${UPASS}'"}' https://hub.docker.com/v2/users/login/ | jq -r .token)
    EXISTS=$(curl -s -H "Authorization: JWT ${TOKEN}" https://hub.docker.com/v2/repositories/$1/tags/?page_size=10000 | jq -r "[.results | .[] | .name == \"$2\"] | any")
    test $EXISTS = true
}

if docker_tag_exists library/nginx 1.7.5; then
    echo exist
else 
    echo not exists
fi
20
Evgeny Oskin

C’est la solution que j’utilise avec gitlab en utilisant le menu fixe: image stable. 

Assurez-vous que les fonctionnalités client expérimentales sont activées:

echo '{"experimental": "enabled"}' > ~/.docker/config.json

Cela écrasera également votre configuration. Si ce n'est pas une option, vous devez le faire manuellement ou utiliser jq, sed ou tout ce dont vous disposez.

S'identifier

docker login -u $USER -p $PASSWORD $REGISTRY

Vérifiez si c'est là:

docker manifest inspect $IMGNAME:$IMGTAG > /dev/null ; echo $?

docker retournera 0 en cas de succès ou 1 en cas d'échec. 

6
morty

Voici une fonction Bash qui aidera:

docker_image_exists() {
  local image_full_name="$1"; shift
  local wait_time="${1:-5}"
  local search_term='Pulling|is up to date|not found'
  local result="$((timeout --preserve-status "$wait_time" docker 2>&1 pull "$image_full_name" &) | grep -v 'Pulling repository' | egrep -o "$search_term")"
  test "$result" || { echo "Timed out too soon. Try using a wait_time greater than $wait_time..."; return 1 ;}
  echo $result | grep -vq 'not found'
}

Exemple d'utilisation:

docker_image_exists elifarley/docker-dev-env:Alpine-sshd && \
  echo EXISTS || \
  echo "Image does not exist"
2
Elifarley

Pour utiliser morty 's answer , notez que docker prend en charge définition du drapeau expérimental à l'aide de la variable d'environnement :

DOCKER_CLI_EXPERIMENTAL Activer les fonctionnalités expérimentales pour le cli (par exemple enabled ou disabled)

L'extrait devient alors:

tag=something
if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $image:$tag >/dev/null; then
    Do nothing
else
    Build and Push docker image with that tag
fi
1
Matěj Laitl

J'aime les solutions basées sur docker.

Ce oneliner est ce que j'utilise dans notre CI:

 docker run --rm anoxis/registry-cli -l user:password -r registry-url -i docker-name | grep -q docker-tag || echo do something if not found
1
ramigg

Vous pouvez simplement essayer de tirer et voir si vous êtes à jour (vous voudrez peut-être baliser votre image locale en premier, mais au cas où la télécommande serait plus récente):

docker pull deepdriveio/deepdrive:env-3.0
env-3.0: Pulling from deepdriveio/deepdrive
Digest: sha256:3b6b6514f79a551b47896f908a2de00b55df1db22f5908c8436feaa12310dfa3
Status: Image is up to date for deepdriveio/deepdrive:env-3.0
0
crizCraig

J'avais du mal à faire en sorte que cela fonctionne pour un référentiel de hub de docker privé et j'ai finalement décidé d'écrire un script Ruby à la place, qui fonctionne à partir d'aujourd'hui. N'hésitez pas à utiliser!

#!/usr/bin/env Ruby
require 'base64'
require 'net/http'
require 'uri'

def docker_tag_exists? repo, tag
  auth_string = Base64.strict_encode64 "#{ENV['DOCKER_USER']}:#{ENV['DOCKER_PASSWORD']}"
  uri = URI.parse("https://registry.hub.docker.com/v1/repositories/#{repo}/tags/#{tag}")
  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = "Basic #{auth_string}"
  request['Accept'] = 'application/json'
  request['Content-Type'] = 'application/json'
  response = Net::HTTP.start(request.uri.hostname, request.uri.port, use_ssl: true) do |http|
    http.request(request)
  end
  (response.body == 'Tag not found') ? 0 : 1
end

exit docker_tag_exists? ARGV[0], ARGV[1]

Remarque: vous devez spécifier DOCKER_USER et DOCKER_PASSWORD lorsque vous appelez ceci comme ...

DOCKER_USER=XXX DOCKER_PASSWORD=XXX config/docker/docker_hub.rb "NAMESPACE/REPO" "TAG" && echo 'latest'

Cette ligne afficherait "dernière" si l'authentification réussissait et que la balise spécifiée n'existait pas! J'utilisais cela dans mon Vagrantfile lorsque j'essayais d'extraire une balise basée sur la branche git actuelle:

git rev-parse --symbolic-full-name --abbrev-ref HEAD

0
mfittko

Le plus simple:

docker pull Alpine:invalid > /dev/null && echo "success" || echo "failed"

Tirages et impressions succès si l'image existe, ou impressions échouées si elles ne pas:

Vous pouvez même l'exporter dans une variable si vous utilisez le script bash:

enter image description here

0
mayankcpdixit

Avez-vous essayé quelque chose comme ça, en essayant simplement de tirer l'étiquette et en décidant de Push ou non en fonction du code de retour?

#! /bin/bash

if docker pull hello-world:linux > /dev/null; then
  echo "already exist -> do not Push"
else
  echo "does not exist -> Push"
fi
0
Romain

Juste une petite amélioration de solution d'Evgeny Oskin . Quand il s'agit d'un repo utilisateur qui n'a pas encore été créé, jq dit qu'il "ne peut pas itérer sur null". Pour le surmonter. on peut ignorer les blocs non présents avec ? Voici une modification de la solution susmentionnée qui s'applique aux un repo public en particulier:

#!/usr/bin/env bash

function docker_image_tag_exists() {
    EXISTS=$(curl -s https://hub.docker.com/v2/repositories/$1/tags/?page_size=10000 | jq -r "[.results? | .[]? | .name == \"$2\"] | any")
    test ${EXISTS} = true
}

if docker_image_tag_exists $1 $2; then
    echo "true"
else
    echo "false"
fi
0
silk