The basics

An exemplary docker image has the following 3 parts:

Pull an image using name

Examples:

docker pull golang

docker pull yugabytedb/yugabyte

docker pull quay.io/keycloak/keycloak-x

When an image is pulled using only the name, the image tagged latest is pulled. If there is no image with the tag latest, then no image will be pulled.

Pull an image using name:tag

Examples:

docker pull golang:latest

docker pull golang:1.17.1

docker pull yugabytedb/yugabyte:latest

docker pull yugabytedb/yugabyte:2.9.0.0-b4

docker pull quay.io/keycloak/keycloak-x:latest

docker pull quay.io/keycloak/keycloak-x:15.0.2

An image like golang is available for multiple os/arch, example: windows/amd64, linux/amd64, etc. In such cases, docker automatically pulls the appropriate image for the os/arch the pull command is run on.

Use this command to view os/arch’s of an image:

docker manifest inspect --verbose golang:1.17.1

# sample output
[
  {
    "Ref": "docker.io/library/golang:1.17.1@sha256:232a180dbcbcfa7250917507f3827d88a9ae89bb1cdd8fe3ac4db7b764ebb25a",
    "Descriptor": {
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "digest": "sha256:232a180dbcbcfa7250917507f3827d88a9ae89bb1cdd8fe3ac4db7b764ebb25a",
      "size": 1796,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    .
    .
    .

A common thing that happens with a tag is that it could be reused. For example an image pulled using golang:latest today may be completely different from an image pulled in 6 months.

Tags that look like version numbers can have the same behavior. There is no guarantee that an image pulled using golang:1.17.1 today (on say linux/amd64) will be the same when pulled 6 months later (again on linux/amd64).

Caution needs to be exercised in production environments when pulling an image using the latest tag since it makes rollbacks harder.

Pulling an image using name@sha256:digest

A digest is an id that is automatically created during build time and cannot be changed (immutable). When an image is pulled using a digest, a docker pull will download the same image every time on any os/arch. This is called image pinning.

First, determine the image name:tag you wish to use. Then get the digest as follows:

docker manifest inspect --verbose golang:1.17.1

# sample output
[
  {
    "Ref": "docker.io/library/golang:1.17.1@sha256:232a180dbcbcfa7250917507f3827d88a9ae89bb1cdd8fe3ac4db7b764ebb25a",
    "Descriptor": {
      "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
      "digest": "sha256:232a180dbcbcfa7250917507f3827d88a9ae89bb1cdd8fe3ac4db7b764ebb25a",
      "size": 1796,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    },
    .
    .
    .

docker manifest inspect --verbose yugabytedb/yugabyte:2.9.0.0-b4

docker manifest inspect --verbose quay.io/keycloak/keycloak-x:15.0.2

The above command returns a JSON response. Look for the digest in the Descriptor.

Examples:

# golang 1.17.1 for linux/amd64
docker pull golang@sha256:232a180dbcbcfa7250917507f3827d88a9ae89bb1cdd8fe3ac4db7b764ebb25a

# yugabyte 2.9.0.0-b4 for linux/amd64
docker pull yugabytedb/yugabyte@sha256:974219f34a18afde9517b27f3b81403c3a08f6908cbf8d7b717097b93b11583d

# keycloak-x 15.0.2 for linux/amd64
docker pull quay.io/keycloak/keycloak-x@sha256:a6b7be1808b8443dde696c5f108be1cb6e7641d6b281ef7598df012c1d6871f8

Note: Comments added above only for readability.

So what should you use?

Well, that depends on your use case. A general guideline that I use for my workflows is:

Quick Recap

Thank you for taking the time to read this article. I hope the information here helps you with image pulls for your use cases and workflows.