Reputation: 8474
When I build image in CI I push it with a unique SHA tag. Then when I deploy it to production I want to change :latest
alias to point to the same image like so:
docker pull org/foo:34f8a342
docker tag org/foo:34f8a342 org/foo:latest
docker push org/foo:latest
Now I want to avoid pulling this image. The problem is that container for deploy script is different from container that was used to build it so I don't have this image locally. Is there any way to add a tag alias on docker hub without the need to have this image locally?
Upvotes: 21
Views: 10579
Reputation: 16044
docker buildx imagetools create --tag new-tag existing-tag
Order of the arguments matters and this requires Docker Buildx. However, quoting the docs:
As of Docker Engine 23.0 and Docker Desktop 4.19, Buildx is the default build client.
(...)
Docker Buildx is installed by default with Docker Desktop. Docker Engine version 23.0 and later requires that you install Buildx from a separate package. Buildx is included in the Docker Engine installation instructions.
And so, in many distributions docker 23+ package installs buildx automatically. You can check if you have buildx already with:
docker buildx version
docker manifest create
didn't work for me in case of multi-manifest images, e.g. multi-platform or with attestation. Below is a sanitized example with parts of manifest JSON skipped for readability:
$ docker manifest create new-tag existing-tag
Error: existing-tag is a manifest list
$ docker manifest inspect -v existing-tag
[
{
"Ref": "existing-tag@sha256:abc",
"Descriptor": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"OCIManifest": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
...
},
... other image layers go here ...
]
}
},
{
"Ref": "existing-tag@sha256:xyz",
"Descriptor": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
"OCIManifest": {
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"layers": [
{
"mediaType": "application/vnd.in-toto+json",
...
}
]
}
}
]
As you can see the tag points to a manifest list with first being a docker image consisting of layers, while the second is an attestation manifest. This seems to break the docker manifest create
command.
What worked well for me in this case is using the newer docker buildx imagetools create command like so:
$ docker buildx imagetools create --tag new-tag existing-tag
[+] Building 1.6s (1/1) FINISHED
=> [internal] pushing new-tag
... which seems to play well with multi-manifest images. Specifically, docker manifest inspect -v new-tag
showed the same output as docker manifest inspect -v existing-tag
Upvotes: 1
Reputation: 997
In my case, I had to add an extra tag to an existing multi arch image. Docker tag would not work, because it would pull and tag only the image matching my OS.
I didn't want to use docker buildx imagetools create
again because it would create a new imageIndex.
I used Skopeo copy command.
skopeo --multi-arch=index-only copy docker://<IMAGE>:<TAG> docker://<IMAGE>:<NEW TAG>
Upvotes: 0
Reputation: 3016
Using the experimental docker manifest
command:
docker manifest create $REPOSITORY:$TAG_NEW $REPOSITORY:$TAG_OLD
docker manifest push $REPOSITORY:$TAG_NEW
For a private registry, you may need to prepend $REGISTRY/
to the repository.
Upvotes: 21
Reputation: 343
As it can be seen here its not allowed, but if the problem is that pulling the entire image is slow as someone mentions in the comments it can be acheived faster just "pulling" the manifest as here through the Docker Registry API
MANIFEST=$(curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "${REGISTRY_NAME}/v2/${REPOSITORY}/manifests/${TAG_OLD}")
curl -X PUT -H "Content-Type: application/vnd.docker.distribution.manifest.v2+json" -d "${MANIFEST}" "${REGISTRY_NAME}/v2/${REPOSITORY}/manifests/${TAG_NEW}"
Upvotes: 5
Reputation: 3022
I'm not aware of tagging a docker image directly on docker hub. There's a workaround for your problem, that is tagging the image with two tags when building it. docker build
allows to create multiple tags for one build:
docker build -t org/foo:34f8a342 -t org/foo:latest .
Upvotes: 1