Referring to images unambiguously

Previously, when we named our image, we simply called it railsapp. Similarly, Compose automatically named our web service image myapp_web.

Although these names worked fine when working on a single Docker Machine, they are not suitable for sharing our image on a Docker Registry. Why? Because what if different people, teams, or organizations all want to have an image called railsapp or myapp_web?

How would we know which image to refer to?

This is a solved problem. By referring to both the image name and a user account, we disambiguate which image we are referring to and allow people to call their images whatever they like without fear of name clashes.

Naming convention

We refer, unambiguously, to a particular image (more precisely, a specific version of an image) by using the following naming convention:

[<registry hostname>[:port]/]<username>/<image name>[:<tag>]

The Registry hostname is optional; leaving it out indicates you are referring to the default Registry: Docker Hub.

If a Registry hostname is provided without an explicit port, the standard SSL port 443 is assumed.

An account is needed to store images on a Registry, and an account can house any number of distinctly named images. The < username>/< image name> combination refers to the particular image in a given user account.

In fact, everything up until the optional tag is known as the repository name:

[<registry hostname>[:port]/]<username>/< image name>

A repository can store multiple tagged versions of the image. We refer to a particular version of the image either by specifying an explicit tag or by letting the default tag—latest—be used.

For example, in educative1/railsv21 username is educative1, and railsv21 is the latest version of an image named railsv21 on Docker Hub.

Docker official images

You may be wondering how we were able to download images like ruby:2.7, redis, and postgres that are not fully qualified image names. Good question. Docker elevates certain popular images by calling them Docker Official Images.

These are placed in a special, top-level namespace that lets you refer to them simply by their image name. However, for our own images, we will always need to use fully qualified image names that include our repository name.

Pushing our image to a registry

We can share our image by pushing it to a Docker Registry. We will use Docker Hub since it’s free (within certain limits), requires no setup, and is the default.

Right now, we are more concerned with sharing the production (rather than development) version of our image, although sharing the development image works in exactly the same way.

Bear in mind throughout this section that on a real project, we wouldn’t build and push images ourselves from our local machine. This would happen automatically as part of our CI pipeline. However, there’s no shortcut to it so learning how to do this manually will put you in good stead for setting up your CI.

Build and tag the image

First, we need to tag our image with the correct repository name we want to push it to. If our image is already built, we could tag it with the command:

$ docker tag <image ref> <your_username>/<image_name>

where < image ref> is either an image ID or a name we have already given it. However, to build and tag our production image in one go, use:

$ docker build -f Dockerfile.prod -t <your_username>/myapp_web:prod .

option -f

The -f option lets us specify the name of a different filename for the Dockerfile to build the image from: in this case, our production image (Dockerfile.prod).

option -t

The -t option tags the image with <your_username>/myapp_web:prod. This indicates the repository <your_username>/myapp_web on Docker Hub and a specific tag of prod.

Push the image

The next step is to push our image to our Docker Hub repository. First, log in to Docker Hub account from the CLI using the following command, and then enter your (Docker Hub) username and password when prompted:

$ docker login

Login with your Docker ID to push and pull images from Docker Hub.

Note: If you don’t have a Docker ID, head over to https://hub.docker.com to create one.

After log-in, to push our image to our Docker Hub account, use:

$ docker push <your_username>/myapp_web:prod

🍀 Practice

Let’s try to push the file to the repository.

  1. Tag and build your image.
  2. Log in to your account.
  3. Push the built image to your repository.

Note: The image building with Dockerfile.prod will take around 10 minutes. If you want to build the image quickly, use Dockerfile. It contains an already built image that can help you grasp the image sharing concept without waiting too long.

Get hands-on with 1400+ tech skills courses.