Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

How to name, version, and reference container images

January 28, 2025
Valentin Rothberg
Related topics:
Automation and managementContainersGitOpsSystem Design
Related products:
Image mode for Red Hat Enterprise LinuxRed Hat Enterprise LinuxRed Hat OpenShift Container Platform

Share:

    In my time working in the software industry, I have encountered recurring issues involving versioning. Which version scheme should we use for project X? When should we bump the major version? Is this pull request a breaking change? We want to cut a new release, but what should the next version be?

    Versioning schemes communicate new features, bug fixes, and even breaking changes to our users. Some schemes are like a contract with users, giving them guarantees for types of version changes. For instance, a major version bump from version 2.4 to 3.0 usually implies a breaking change and a substantial new functionality. Consumers of software (e.g., Linux distributions) can decide when and how to use the new versions. 

    But not all versioning schemes are equal. Some schemes are more expressive than others. My personal favorite is semantic versioning, which I will elaborate on later in this article. Other versioning issues are naming and tagging container images. This topic comes up all the time in communications with customers, partners, and the community.

    In this article, I will share my lessons learned about naming, tagging, and versioning container images and software. Being decisive in answering the following questions will prevent future headaches and make our lives easier. Are we in control over changes? Which changes can we expect from updates? Is the latest tag any good? What are the advantages and disadvantages of referencing an image by digest? What is semantic versioning? I will attempt to provide answers to these questions and more.

    What is an image reference

    Let’s discuss terminology before digging into the details of naming and tagging conventions, versioning schemes, and digests.

    We rarely ask ourselves which version, tag, or digest to use when working with containers—at least on our workstations. As outlined in an earlier article, container engines such as Podman allow for a great user experience by resolving short names to a real reference of a container image. For instance, doing a podman pull fedora will pull the registry.fedoraproject.org/fedora:latest image. I love that experience on my workstations because I don’t have to type much and Podman knows better where to pull an image.

    However, we should be more careful when moving our workloads to production. Choosing the wrong tag may result in future downtimes and hours of debugging. To make sure we are all on the same page, let’s look at the different parts of a container image reference, as shown in Figure 1.

    The different components of a container image.
    Created by Valentin Rothberg,
    Figure 1: The different components of a container image.

    A reference can contain a domain (quay.io) pointing to the container registry, one or more repositories (also referred to as namespaces) on the registry (fedora), and an image (fedora-bootc) followed by a tag (41) and/or digest (sha256). Note that images can be referenced by tag, digest, or both at the same time, as shown in Figure 1.

    Repository organization

    Typically, you would scope a registry configuration to repositories (or their parents), so a single repository should contain related images. There are two common ways of organizing repositories:

    1. The most common method is to use a repository to store all versions of a single container image, storing all versions of that application. For example, registry.example/my-frontend:v1.0, registry.example/my-frontend:v1.1, and registry.example/my-frontend:v2.0. A larger distributed application would then use a collection of repositories, one repository per container image (registry.example/my-frontend, registry.example/my-backend, registry.example/my-database).

    2. An alternative method is to distribute the whole distributed application in a single repository, using a more detailed tag convention or digest references (described next) to distinguish between different images. This is the case for Red Hat OpenShift that ships most of the core container images of the product in quay.io/openshift-release-dev/ocp-v4.0-art-dev.

    What is an image tag

    A tag points to an image on a given registry and repository. There is no strict enforcement on how to use tags, but there are certain conventions. For instance, tags are frequently used to version images (e.g., fedora:40, fedora:41). In the early container days, tags were also used to ship a given image in multiple architectures (e.g., image:version-arm64, image:version-s390x). 

    An important attribute of tags is that they are mutable. A given tag may point to a specific image today but can point to another updated image in the future.

    Should you use the latest tag

    As a convenience to users manually entering commands in a CLI, container engines default to using the latest tag if the user has not provided a tag or digest. By convention, it is expected that the latest tag points to the most recent image, so defaulting to it makes sense for a great user experience. When we run podman run fedora, we just want to get the latest and greatest version of Fedora without worrying about the exact details. This is perfect for an interactive experience.

    But should we use the latest tag in production? My general answer is no. Today, the tag may point to Fedora 41, but it will certainly point to another version in future with potentially breaking changes to the workload.

    In the end, it boils down to understanding the stability and support guarantees of the given name and tag we use. As an end user, we have no control over the changes going into the Fedora latest tag. But if we are building an image on our own and have full control and ownership over the changes going in, it is perfectly fine to use the latest tag.

    When deciding which tag to use, we must consider whether we are in control over the images we consume and if we are at risk of running into breaking changes at some point. Using the latest tag is certainly tempting because it is easy and straightforward, but we need to be aware of what we’re up against.

    What is an image digest

    In contrast to a tag, a digest guarantees which image we will consume. I previously discussed the digest in reference to fully-qualified image references. A digest refers to a specific image on a registry, which means the target can never change. To clarify, the digest is the sha256sum of the JSON image metadata.

    What’s so special about digests? A tag is a pointer that can direct to any image and change over time, but a digest identifies exactly one image, namely the one with the matching sha256sum on the registry and namespace. Pulling an image by digest will fail if there is no matching image on the registry.

    Let’s do a quick experiment to highlight the nature of a digest. For that purpose, we'll use Skopeo, a container image tool. Skopeo is like a Swiss Army Knife for all things related to container images and has been dedicated to the CNCF in late 2024 along with Podman, Podman Desktop, bootc, and Buildah.

    As mentioned, the digest is the sha256sum of the JSON metadata of a given image. We can query the metadata via skopeo inspect. The following shows the digest specified to the image is the exact sha256sum:

    $ skopeo inspect --raw docker://fedora@sha256:3ec60eb34fa1a095c0c34dd37cead9fd38afb62612d43892fcf1d3425c32bc1e | sha256sum
    3ec60eb34fa1a095c0c34dd37cead9fd38afb62612d43892fcf1d3425c32bc1e  -

    This exercise demonstrates that we will get exactly the requested image when using a digest.

    When to use a digest

    I recommend referencing an image by digest when you need to be in full control over which image to use. This can be beneficial in production use cases where we use and run the one image that has been fully tested and released. We could use a tag, but the digest has the additional benefit of being unique. The tag points to an image that may always change, intentionally or accidentally.

    The main idea is to be aware, intentional, and control the images we consume and the image changes. In an article about CI/CD pipelines for Image Mode for RHEL, we elaborated on the benefits of referencing an image by digest to achieve a GitOps-like workflow to build and manage bootc images in a fully automated fashion. Dependency-management bots will automatically open a pull request to update the digest in our Containerfile, so we have full control of the changes. We are making use of this setup to manage a bootc-based workstation here. Figure 2 illustrates automated digest updates to a Dockerfile.

    Automated digest updates to a Dockerfile.
    Created by Valentin Rothberg,
    Figure 2: Automated digest updates to a Dockerfile.

    In summary, referencing an image by digest expresses the intent to use one specific image. Using a digest renders container builds more reproducible since every build will always use the same base image. A digest further prevents certain pitfalls and human error caused by the ambiguity of tags, and it has certain security benefits since we will only use the exact image requested. You should consider using a digest when you want to solve these issues.

    When to use a tag

    Tags are essential to referencing container images. We've already discussed the benefits of using digests, but those are better for machines. A tag is a way to communicate the contents, version, support, and lifecycle of an image to users.

    Let’s consider the fedora:41 image. By looking at the name Fedora and the tag 41, it is obvious that the tag is the specific version of Fedora. This tells us exactly how long the image will receive updates as the container image follows the documented lifecycle of the Fedora project.

    When should you use a tag? It depends on the use case, requirements, and the target environment. It is crucial to consider which changes we may consume. A tag is only a pointer to an image and can be updated at any time. The 41 tag of the Fedora image will point to another image (i.e., a new digest) whenever the project releases new updates to the image by rebuilding and publishing it.

    Using the 41 tag guarantees that there won’t be any breaking changes during the lifetime of this version of Fedora, so running workloads with this tag is totally acceptable. The low risk of a potential accidental breaking change to an image resulting in breaking my workload isn't worth the additional work of constantly updating the digest to consume updates and security fixes.

    Finding the right balance is also important. Would I reference an image only by tag if my life depended on it? Absolutely not. I would always use a digest. Would I use a tag for my streaming service at home? Absolutely.

    Note that there are other means than using a tag to embed a version. For example, Red Hat’s Universal Base Image embeds the version in the repository registry.redhat.io/ubi9/ubi.

    Best practices for tagging and versioning images

    When it comes to publishing and releasing images, make sure clients can easily consume them. Choosing the right tagging and versioning schemes for your images will pay off in the long term since it impacts workload management. Semantic versioning is an expressive strategy for tagging images. 

    Semantic versioning is like a contract for consumers, using the format X.Y.Z, where incrementing either component has a very specific (semantic) meaning:

    • X: A major version bump with backwards incompatible changes.
    • Y: A minor version bump with new functionality and backwards compatible changes.
    • Z: A patch version bump with bug fixes but without new functionality in a backwards compatible way.

    Using semantic versioning has many advantages over using less expressive versioning schemes such as the latest tag. One advantage is the version of a given image is obvious. Another advantage is that consumers of the image can pin to major and/or minor versions. For instance, using image:2.3 will pin to the version 2.3 and consume all patch updates (e.g., 2.3.1, 2.3.2, etc). Using image:2 will pin to the major version 2 including all minor and patch versions (e.g., 2.1, 2.2, etc). Using image:2.3.1 would pin to this exact version and not include future patch versions. 

    Note that your release pipelines must ensure that the X.Y tags are floating and continuously updated when releasing a patch version.

    The importance of container image versioning

    In summary, there is no best method for consuming, publishing, and referencing container images. There are many best practices out there. Whether we rely on tags, digests, semantic versioning, or other versioning schemes and naming conventions, it all boils down to being decisive about what we publish and consume. Our use cases, requirements, and the degree of automation should determine what’s best in a given environment. I hope that this article will help you navigate this space. 

    Last updated: January 29, 2025

    Related Posts

    • Image mode for RHEL: 4 key use cases for streamlining your OS

    • bootc: Getting started with bootable containers

    • Announcing image mode for Red Hat Enterprise Linux

    • Verifying signatures of Red Hat container images

    • Container Images for OpenShift - Part 1: Objectives

    Recent Posts

    • More Essential AI tutorials for Node.js Developers

    • How to run a fraud detection AI model on RHEL CVMs

    • How we use software provenance at Red Hat

    • Alternatives to creating bootc images from scratch

    • How to update OpenStack Services on OpenShift

    What’s up next?

    Learn how to utilize GitOps in OpenShift to manage your virtual machines (VMs) in this learning path.

    Start the activity
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue