So I have a private repository at docker hub
and I am trying to download image (blobs) manually using HTTP API.
Now there are some issues
- I have tried https://hub.docker.com/support/doc/how-do-i-authenticate-with-the-v2-api
and this script works and I can see my tags.
But there is no API in docker HUB api to get list of blobs from a tag and then download it.
There is a docker registry api, but there my username password does not work.
What to do?
2
Answers
For an image, you first pull the manifest and parse that for the list of blobs that you need to pull. All of these API’s need the same authorization headers used to list the tags. I’m going to be using regctl from my regclient project to query a local registry, but you could also use curl against Hub which I show below.
A few examples if you try doing this with curl:
Get a token (specific to Docker Hub, each registry may have different auth methods and servers):
To use a user/password rather than an anonymous login, call curl with the
-u user:pass
option:Tags:
Manifests:
And blobs:
If you want to export everything to be able to later import,
regctl image export
will convert the image to a tar of manifests and blobs. This is output in the OCI Layout format, and if you only pull a single image manifest (and not a multi-platform manifest) it will also include the needed files fordocker load
to import the tar.It probably depends on how you supply them. I didn’t try it with a private repository on Docker Hub, but here’s a script that downloads public images from Docker Hub, and images from private registries:
Usage:
Or to be more precise it retrieves the image config and the layers. The thing is, what are you going to do with them? You can try to create a tar archive that looks like the one produced by
docker save
. Which is whatdocker-drag
basically does. But ideally for that you should know what exactlydocker pull
anddocker save
do.To give you some links to the source code,
docker pull
(the server part) more or less starts here:https://github.com/moby/moby/blob/v20.10.18/api/server/router/image/image.go#L37
https://github.com/moby/moby/blob/v20.10.18/api/server/router/image/image_routes.go#L78
https://github.com/moby/moby/blob/v20.10.18/daemon/images/image_pull.go#L54
https://github.com/moby/moby/blob/v20.10.18/daemon/images/image_pull.go#L130
https://github.com/moby/moby/blob/v20.10.18/distribution/pull.go#L52
Most of the relevant code is in
distribution/pull_v2.go
(the high-level part).The code that does the http requests is in
vendor/github.com/docker/distribution/registry/client/auth/session.go
andvendor/github.com/docker/distribution/registry/client/repository.go
.docker save
:https://github.com/moby/moby/blob/v20.10.18/api/server/router/image/image.go#L31
https://github.com/moby/moby/blob/v20.10.18/api/server/router/image/image_routes.go#L160
https://github.com/moby/moby/blob/v20.10.18/daemon/images/image_exporter.go#L16
https://github.com/moby/moby/blob/v20.10.18/image/tarexport/save.go#L187
Most of the code is in
image/tarexport/save.go
.But well, apparently
docker-drag
‘s developer didn’t concern himself with it, and it (docker-drag
) seems to work.In case of private Docker Hub repositories you probably need to add
-u user:password
to the$realm?service=$service&scope=$scope
request.A couple of remarks about using the API:
user/name
(e.g.nginxproxy/nginx-proxy
). But with official repositories (that all in fact start withlibrary/
) the first segment may be omitted (library/ruby
->ruby
). Also there might be just one segment (e.g. in private registries), and occasionaly the first part alone is called a repository (example). Or the second./v2/_catalog
route.