作为bash脚本的一部分,我想检查docker hub上是否存在特别的docker image:tag组合。此外,它将是一个私人存储库。
即伪代码如下:
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使用gitlab的解决方案:稳定的图像。
确保启用了实验性客户端功能:
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。
这是一个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
要建立在morty的answer上,请注意docker支持setting the experimental flag using environment variable:
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
我正在努力让这个工作用于私人码头中心存储库,最后决定编写一个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
您可以尝试拉动并查看您是否是最新的(您可能希望首先标记本地图像,以防远程更新):
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
你有没有试过这样的东西,根据返回码只是试图拉动标签并决定是否按下?
#! /bin/bash
if docker pull hello-world:linux > /dev/null; then
echo "already exist -> do not push"
else
echo "does not exist -> push"
fi