Docker Images: Name Vs. Tag Vs. Digest

Written by vijaysavanth | Published 2021/09/26
Tech Story Tags: docker-image | docker | name-vs-tag-vs-digest | programming | tutorial | coding | tag-vs-digest | docker-pull

TLDRA docker image usually has 3 parts: name, tag, and digest. Images can be pulled using name, or name:tag or name@sha256:digest. Some images are multi-architecture images. In such cases, docker automatically pulls the appropriate image for the os/arch the pull command is run on. Use docker manifest inspect --verbose <name:tag> to view os/arch’s of an image and to get the digest. Avoid using the latest tag in a product environment since it makes rollbacks hard. via the TL;DR App

The basics

An exemplary docker image has the following 3 parts:

  • Name (required, user-specified at build time)
  • Tag (optional, user-specified at build time)
  • Digest (automatically generated at build time)

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:

  • Experimenting on your local machine? It’s ok to pull using name or name:tag.
  • Building an image for production? Use name@sha256:digest to pull your base image(s). This ensures that the same final image is built on any machine.
  • Deploying an image to a production environment?
    • If the image was built by your team (or company), it’s ok to use name:tag where a tag represents a version number, for example v21.10.1. Avoid using the latest tag since it makes rollbacks harder.
    • If the image was not built by your team (or company), use name@sha256:digest if possible. If you choose to use name:tag, be mindful that tags can be reused. Avoid using the latest tag since it makes rollbacks harder.

Quick Recap

  • A docker image usually has 3 parts: name, tag, and digest.
  • Images can be pulled using name, or name:tag or name@sha256:digest.
  • Some images are multi-architecture images. Pulling a multi-architecture image using name or name:tag will automatically download the appropriate image for the os/arch the pull command is run on.
  • Use docker manifest inspect --verbose <name:tag> to view os/arch’s of an image and to get the digest.
  • Pull an image using name@sha256:digest to download the same image on any os/arch.
  • Avoid using the latest tag in a product environment since it makes rollbacks hard.

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.


Written by vijaysavanth | Entrepreneur, Designer & Engineer. Based in Tāmaki Makaurau, Aotearoa (Auckland, New Zealand).
Published by HackerNoon on 2021/09/26