---
title: "Docker Terminology & Concepts"
order: 1
---

While Docker users rarely need to worry about implementation details, they can become important when managing and troubleshooting a private Docker registry.

Below is a brief guide that will familiarize you with the basic terminology and concepts of Docker.

Registry; a registry is a Docker feed in ProGet, but in general it's a server that hosts Docker repositories and associated metadata. `registry-1.docker.io` and `mcr.microsoft.com` are also registries.

**Repository**; a repository is contained in a _registry_ and is basically just the name of a container and a collection of _tags_. It's something like a package name. For example, `inedo/proget` and `dotnet/core` are repository names, but don't refer to a specific _image_.

**Image**; an image, or container image, is what many people think of when they say "container".  The Docker client downloads images from a _repository_ and runs an image as a _container_. Behind the scenes, an image is comprised of a _manifest_ and a set of _layers_ described in that manifest. 

**Layer**; a layer is a .tar archive file (like a .zip file) that represents a "file system snapshot". Extracting a number of layers on top of each other (i.e. in the same directory) gives the file system used by a _container_.

When you use Docker Client to create a container image, each command generates a new snapshot. Before running a container image, Docker Client assembles all the layer files to create the file system.

Layers can be stored in the registry (as _blob_) or as _url_. Many Windows-based images use url-based layers, perhaps for licensing reasons.

**Blob**; blobs are the low-level storage mechanism in a _registry_, and they're basically just files without a name. Instead of using filenames, blobs are accessed by their _digest (hash)_. This means that humans can't really work with blobs, and you need a _tag_ or a _manifest_ to reference them in a meaningful way.

Blobs are used to store _layers_ (.tar files) and _container configuration files_ (.json files). In Docker v1, blobs were used to store _manifests_ (.json files), but these are now stored separately.

**Digest (hash)**; digest and hash are generally synonymous in Docker terminology, and both refer to the SHA256-based hash of a _blob_. It's effectively the "filename" of a blob - but since it's automatically generated by the contents of the file, it can never be changed.

**Tag**; this is the way container images in a _repository_ are accessed by humans. Essentially, it's a human-readable alias of the _digest (hash)_ of a _manifest_. Tags aren't part of the image metadata itself, they're simply a label provided by the repository hosting the corresponding images (be it the Docker client's local repository, Docker Hub, ProGet, etc.).

For example, the tags `inedo/proget:5.3.1` and `inedo/proget:5.3.2-ci.4` would point to these container images.

A tag is formatted with two parts (`«image-name»:«tag»`), which can be a bit confusing because the second part of the tag is also called a tag. As such, "tag" (an alias of a manifest's digest) and "tag" (the second part of a tag) are often used interchangeably. 

In practice, tags (manifest digest aliases) are `«image-name»:«version-like-string»`, and the `«version-like-string»` can convention-driven words (like `latest` or `latest-v6`) or semantic versions.

**Manifest**. A manifest is a JSON document that lists all _layers_ of the _image_, which can be either _blobs_ or URLs. It may contain the _digest_ for a _container configuration file_ in a "config" element.

Like everything else in Docker, manifests can only be found via a _digest (hash)_, even if they are not blobs. In practice, manifests are referenced by a _tag_ that provides the required digest.


**Container configuration file**. This is a JSON document stored as a _blob_ and referenced via the "config" element of an image _manifest_. It's generated by the Docker client at build time and contains metadata used to run the image, such as environment variables, open ports, operating system, etc.

Container configuration files are optional, and not all container images use them.

**Manifest list (fat manifest)**. A manifest list is a type of "virtual" image that allows users to reference multiple container images for different architectures (e.g. AMD/Intel x64 or ARM, etc.) with a single _tag_.

A manifest list is a JSON document that lists *other* image _manifests_, along with their architectures. For example, the hypothetical tag `fatimg/java-jdk:5.2.1` could refer to a _manifest list_ instead of a _manifest_. In this case, the Docker client would search the list for a compatible architecture (e.g. x64) and then follow the _digest_ to find the manifest file, and then start assembling the image.

**Dockerfile** is a code file written in a proprietary programming language. It's processed by the Docker client to create an _image_ by creating file system snapshots after each command (these become _layers_) and then building a _manifest_ and a _container configuration file_.