web-dev-qa-db-ja.com

image:tagの組み合わせがdockerハブに既に存在するかどうかを確認します

Bashスクリプトの一部として、特にdocker image:tagの組み合わせがdockerハブに存在するかどうかを確認したいと思います。また、プライベートリポジトリになります。

つまり、擬似コードは次のようになります:

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

これをお試し下さい

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

更新:

Docker Registry v2を使用する場合( 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
29
Evgeny Oskin

これは、docker:stableイメージを使用してgitlabで使用するソリューションです。

実験的なクライアント機能が有効になっていることを確認してください

環境変数を設定します DOCKER_CLI_EXPERIMENTAL to enabled(以下のMatějの回答を参照)

または、構成を調整します(元の回答):

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

これも設定を上書きします。それがオプションでない場合は、手動で行うか、jqsed、または利用可能なものを使用する必要があります。

ログイン

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

そこにあるかどうかを確認します:

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

dockerは成功すると0を、失敗すると1を返します。

16
morty

mortyanswer に基づいてビルドするには、dockerが 環境変数を使用して実験フラグを設定する をサポートしていることに注意してください。

DOCKER_CLI_EXPERIMENTAL CLIの実験的な機能を有効にします(例:enabledまたはdisabled

したがって、スニペットは次のようになります。

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
5
Matěj Laitl

役立つBash関数を次に示します。

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'
}

使用例:

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

Dockerに基づくソリューションが好きです。

このonelinerは私が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

最も簡単:

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

画像が存在する場合は成功success、存在しない場合はfailedをプルして印刷します't:

Bashスクリプトで使用する場合は、varでエクスポートすることもできます。

enter image description here

1
mayankcpdixit

Evgeny Oskin's solution のほんの少しの改善。まだ作成されていないユーザーリポジトリに関しては、jqは「nullを反復処理できない」と言います。それを克服するために。 ?で存在しないブロックをスキップできます。ここでは、パブリックリポジトリに適用できる上記のソリューションの変更を示します。特に:

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

引っ張ってみて、最新かどうかを確認することができます(リモートがより新しい場合に備えて、最初にローカルイメージにタグを付けることができます)。

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

これをプライベートDockerハブリポジトリで動作させるのに苦労していたので、代わりにRubyスクリプトを記述することにしました。

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

注:これを呼び出すときは、DOCKER_USERとDOCKER_PASSWORDを指定する必要があります...

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

認証が成功し、指定されたタグが存在しない場合、この行は「最新」を出力します!現在のgitブランチに基づいてタグを取得しようとしたときに、Vagrantfileでこれを使用していました。

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

0
mfittko

あなたはそのようなことを試みましたか、単にタグを引っ張って、プッシュするか、リターンコードに従っていないかを決定しようとしましたか?

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