Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When would a Docker image and its repository have different names?

The standard usage of the docker tag command is:

docker tag <image> <username>/<repository>:<tag>

So for example: docker tag friendlyhello john/get-started:part1.

Coming from Java-land, I'm used to Maven/Gradle-style coordinates of group:artifact:version, so to me, it makes sense for the image and the repository to be one in the same:

The image is the artifact you're producing, and in Java-land there's usually a 1:1 relationsip between the generated artifact and the source repo its code lives inside of. So to me, it makes more sense for the command to be just:

docker tag <username>/<repository>:<tag>

So for example: docker tag john/get-started:part1, where john is the username/group, get-started is the artifact/repo and part1 is the tag/version.

TO BE CLEAR: I am not asking what the difference is between an image and a repository! I understand that a repository is a location where images are stored, and I understand that an image is a Docker executable consisting of your Dockerized app and its dependencies. But from a naming standpoint, I'm confused as to why/when they should ever be different from each another.

So I ask: what is the difference between an image and a repository from a naming convention standpoint? For example if I wanted to make my own MySQL Docker image, I'd chose to make the image named "myapp-db", and that would also be the name of the repository where it lived (smeeb/myapp-db:v1, smeeb/myapp-db:v2, etc.).

So under what circumstances are/should image and repository names be different?

like image 838
smeeb Avatar asked Jun 12 '17 13:06

smeeb


People also ask

Can two docker images have the same name?

Multiple tags may refer to the same image. If you reassign a tag that is already used, then the original image will lose the tag, but will continue to exist (it will still be accessible by its image ID, and other tags might refer to it).

What is docker repository name?

The repository name needs to be unique in that namespace, can be two to 255 characters, and can only contain lowercase letters, numbers, hyphens ( - ), and underscores ( _ ). Note: You can't rename a Docker Hub repository once it's created. The description can be up to 100 characters and is used in the search result.

What is the naming convention of a docker image?

Description. An image name is made up of slash-separated name components, optionally prefixed by a registry hostname. The hostname must comply with standard DNS rules, but may not contain underscores. If a hostname is present, it may optionally be followed by a port number in the format :8080 .


3 Answers

First a prerequisite: a tag is a pointer to an image, and an image is a sha256 reference to a manifest of configuration and layers that docker uses to make containers. What that means is that friendlyhello is not the name of an image, it's a tag that points to an image. The image is the id, something like c75bebcdd211.....

Next, each image can have zero, one, or multiple tags all pointing to it. When it doesn't have any tags pointing to it, that's referred to as a dangling image. That can happen if you build an image with a tag, and then rebuild it. The previous image is now untagged because the tag is pointing to the new image. Similarly you can have the tags image:latest, image:v1, image:1.0.1, and myrepo:5000/image:1.0 all pointing to the same image id.

Tags have a dual use. They can be for convenience. But they are also used by docker push and docker pull to lookup where to send or retrieve the package. If you don't do a push or a pull, then you can name it whatever you want and no one will know the difference. But if you do want to store it on a registry, the tag needs to identify which registry, or the default docker hub. And that tag also needs to identify the path on the registry, called the repository, and the versioning after the colon.

One confusing bit is that the short name at the end of the repository name is often called an "image name", and the versioning after the colon is often called a "tag", and I think this is much easier to understand if you forget those terms were ever overloaded like that.


Now with all that background (sorry, that was a lot), here are a few corrections to the question:

Instead of:

docker tag <image> <username>/<repository>:<tag>

Think of the syntax as:

docker tag <source> <tag>

Where <source> can be an image id, or another tag name. This means the following command won't make sense:

docker tag <username>/<repository>:<tag>

Because docker tag needs a source to tag, and it has no sense of context for what image you are currently working with.


Lastly, why would you use a name other than your repository name for an image, here are a few reasons I've encountered:

  1. The image won't be pushed to a repository. It could be for local testing, or an intermediate step in a workflow, or you build and run your images on the same system.

  2. You may have multiple names for the same image. registry/repo/image:v1 and registry/repo/image:v1.0.1 is a common example. I'll also tag the current image in a specific environment with registry/repo/image:STAGE to note that it made it through dev and CI and is now in the staging environment.

  3. You may be moving images between registries. We pull images from hub.docker.com and retag them locally with a local registry. That gives us both a local cache and also a way to control when we update our base images to the next version. That's preferable to having an update image update in the middle of a production rollout.

  4. I've also used tags to override upstream images. So instead of changing all my build scripts for an issue I have with an upstream image, I can just make my change and tag it with the upstream name. Then as long as I don't run a pull on that docker host, the builds will run using my modified base image.

like image 101
BMitch Avatar answered Oct 26 '22 03:10

BMitch


One situation where you can have an image with a different tag than the repository name is if you have an image in use that is outdated.

For instance you download and run a MySQL:5 image. This container is still running when you pull a newer version of the MySQL:5 image. At that point the old image will be untagged (identifiable only by its hash), but not deleted, because it is still in use by the running MySQL container.

Another situation is that you can have intermediate images while building a new image. Basically each line gets committed as a new image, but they are not named with the name you specify as the final image name.

When using docker tag you don't even have to use the image name as the first parameter. You can even use the hash of the image that you want to tag as the first parameter, so it's more flexible than just namespace/repository:tag.

like image 36
eawenden Avatar answered Oct 26 '22 01:10

eawenden


The difference between an image and repository must be stated:

An image is a tagged repository. That's the only difference. The <username> is part of the repository name.

From the overview of the Docker Registry Distribution API:

Classically, repository names have always been two path components where each path component is less than 30 characters. The V2 registry API does not enforce this. The rules for a repository name are as follows:

A repository name is broken up into path components. A component of a repository name must be at least one lowercase, alpha-numeric characters, optionally separated by periods, dashes or underscores. More strictly, it must match the regular expression [a-z0-9]+(?:[._-][a-z0-9]+)*. If a repository name has two or more path components, they must be separated by a forward slash ("/"). The total length of a repository name, including slashes, must be less than 256 characters.

Just use meaningful names for your images and tags. You could have smeeb/myapp and smeeb/myapp-db. For tags, the convention is to use versioned tags and a latest one.

like image 27
Ricardo Branco Avatar answered Oct 26 '22 03:10

Ricardo Branco