作为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
答案 0 :(得分:25)
请尝试这个
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
答案 1 :(得分:13)
这是我使用docker:stable镜像与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。
答案 2 :(得分:2)
这是一个有用的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"
答案 3 :(得分:1)
我喜欢基于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
答案 4 :(得分:1)
要在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
答案 5 :(得分:0)
我正在努力让这个工作用于私人码头中心存储库,最后决定编写一个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
答案 6 :(得分:0)
您可以尝试拉动并查看您是否最新(您可能要先标记本地图像,以防遥控器较新):
self.stats['Strength']['rank'].get()
答案 7 :(得分: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
答案 8 :(得分:0)
最简单:
docker pull alpine:invalid > /dev/null && echo "success" || echo "failed"
如果图像存在,则拉并打印成功,如果不存在,则打印失败:
如果在bash脚本中使用,您甚至可以将其导出为var:
答案 9 :(得分:0)
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
答案 10 :(得分:0)
我使用注册表:2,私有CA和基本身份验证在我的LAN上站起了一个docker私有存储库。
我只是看了官方的docker API文档(https://docs.docker.com/registry/spec/api/)并提出了这个解决方案,该解决方案看起来非常优雅,易于调试,自定义并且对CICD /脚本友好。
curl --silent -i -u "demoadmin":"demopassword" https://mydockerrepo.local:5000/v2/rancher/pause/manifests/3.1 | grep "200 OK"
-silent删除了一些多余的文字
-i是显示返回代码“ 200 OK”的原因
如果存在则返回码为0,如果不存在则返回码为1
您可以使用
进行验证
Bash#echo $?
答案 11 :(得分:0)
以上所有选项均假定您可以使用用户名/密码进行身份验证。在很多情况下,这样做很不方便,例如,在使用Google Container Registry时,将首先运行gcloud auth configure-docker gcr.io
。该命令将为Docker安装身份验证帮助程序,而您不想自己管理该令牌。
crane是支持这些Docker身份验证帮助程序并允许获取清单的工具,例如实验性Docker。
使用起重机的示例:
# you would have done this already
gcloud auth configure-docker gcr.io;
# ensure we have crane installed
which crane || (echo 'installing crane' && GO111MODULE=on go get -u github.com/google/go-containerregistry/cmd/crane)
# check manifest
crane manifest ubuntu || echo "does not exist"
答案 12 :(得分:0)
我对这里的一些答案有很多问题。在我看来,最简单的答案是来自 @Evgeny Oskin 的公认答案。
curl 部分起作用了,但由于某些原因,包含 if (fieldName == "examrubric")
{
for (; ; )
{
Console.WriteLine("To enter a row to the tabel type 'yes'\n");
string choice = Console.ReadLine();
if (choice == "yes")
{
Console.WriteLine("Enter a value for the question number:\n");
string qnum = Console.ReadLine();
Console.WriteLine("Enter a value for what the question is out of:\n");
string score = Console.ReadLine();
Console.WriteLine("Enter a value for how much was scored:\n");
string qscore = Console.ReadLine();
Console.WriteLine("Enter a value for score:\n");
string score2 = Console.ReadLine();
Console.WriteLine("Enter the total mark:\n");
string total = Console.ReadLine();
valuesToFill = new Content(
new TableContent("examrubric")
.AddRow(
new FieldContent("qnum", qnum),
new FieldContent("score", score),
new FieldContent("qscore", qscore),
new FieldContent("score2", score2),
new FieldContent("total", total)));
}
else
{
break;
}
}
}
、_
、-
等字符的标签没有被找到,我收到了 404。
最后我用以下解决方案修复了它:
.
这将在 dockerhub 中获取每个标签的 json 文件,然后我们做一些 jq 魔术来过滤图像并检查它是否确实存在。
如果图像不存在,则返回的输出将为空。