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
これをお試し下さい
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
これは、docker:stableイメージを使用してgitlabで使用するソリューションです。
実験的なクライアント機能が有効になっていることを確認してください:
環境変数を設定します DOCKER_CLI_EXPERIMENTAL
to enabled
(以下のMatějの回答を参照)
または、構成を調整します(元の回答):
echo '{"experimental": "enabled"}' > ~/.docker/config.json
これも設定を上書きします。それがオプションでない場合は、手動で行うか、jq
、sed
、または利用可能なものを使用する必要があります。
ログイン
docker login -u $USER -p $PASSWORD $REGISTRY
そこにあるかどうかを確認します:
docker manifest inspect $IMGNAME:$IMGTAG > /dev/null ; echo $?
dockerは成功すると0を、失敗すると1を返します。
morty の answer に基づいてビルドするには、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
役立つ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"
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
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
引っ張ってみて、最新かどうかを確認することができます(リモートがより新しい場合に備えて、最初にローカルイメージにタグを付けることができます)。
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
これをプライベート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
あなたはそのようなことを試みましたか、単にタグを引っ張って、プッシュするか、リターンコードに従っていないかを決定しようとしましたか?
#! /bin/bash
if docker pull hello-world:linux > /dev/null; then
echo "already exist -> do not Push"
else
echo "does not exist -> Push"
fi