Skip to content

Docs feedback - feature proposal: remote image tagging

Problem to solve

Sometimes one needs to add additional tag to image that already exists in registry.

For example, when you build new release of the application and create a container with it - it has to pass tests, checks and so on before being actually released on production. After release, the only thing you need to do to mark this release as 'current production' is to tag it with :latest. At that moment the image definitely exists in registry with all its layers. There is no need to perform

docker login
docker pull ...
docker tag ...
docker push ...

to only update manifest for :latest tag

Intended users

Release Managers. The ones who maintain the CI process in the companies and actively interact with API for procedures automation.

Further details

The remote tagging functionality already exists in docker API v2, but has no implementation in docker CLI utility. We have to pull/push full image on runner just to add tag to it. That's not effective, and we'd like to solve the problem using API. To do this now we have to manually obtain JWT from GitLab API to use it in requests to Registry API. It seems we have to reimplement the logic you already have and use inside the GitLab to work with Registry.

Proposal

The remote tagging feature can be implemented with manifests GET/PUT requests. The docker image tag is actually a special data structure that contains info on image: layers being used and so on. This manifest can be loaded and posted to docker API as JSON.

To get the manifest for tag:

curl \
        --silent \
        -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        -H "Authorization: Bearer ${JWT_TOKEN}" \
        "${REGISTRY_SERVER}/v2/${repository_path}/manifests/${existing_tag_name}"

To create/update tag with given manifest:

echo "${MANIFEST}" | curl \
        --silent \
        -X PUT \
        -H "Content-Type: application/vnd.docker.distribution.manifest.v2+json" \
        -H "Authorization: Bearer ${JWT_TOKEN}" \
        -d "@-" \
        "${REGISTRY_SERVER}/v2/${repository_path}/manifests/${new_tag_name}"

I think that it will be convenient to have GitLab API method for this:

  • POST /projects/:id/registry/repositories/:repository_id/tags/:tag_name, which expects another (existing) tag name to use as source in POST parameters.

Permissions and Security

The same as for other registry actions, like deleting a tag.

Documentation

Document new action in https://docs.gitlab.com/ce/api/container_registry.html and https://docs.gitlab.com/ee/api/container_registry.html

Testing

No idea, sorry. :(

What does success look like, and how can we measure that?

The registry gets new tag for the same image, or existing tag's metadata is updated so it starts to return new image on pull.

What is the type of buyer?

Links / references

Edited by Denis Korenevskiy