Container image

On this page 7

A container image is an immutable, read-only package that contains a filesystem with an application, its libraries and runtime, together with metadata describing how to run it: the default command, environment variables, exposed ports and the user. In cloud computing, and specifically in the field of containers, the image is the build artifact, while a container is a running instance created from that image.

Most images follow the OCI image specification of the Open Container Initiative, which grew out of the Docker image format. An image built with Docker, Buildah or another compliant tool can therefore be stored in any compatible container registry and run by any compliant runtime, which makes the image the portable unit of delivery in cloud-native systems.

How a container image is structured

An image consists of an ordered stack of filesystem layers, a configuration object and a manifest that lists them. Each layer is a compressed archive of file changes: files added, modified or marked as deleted relative to the layer below. At run time, the container engine stacks these layers with a union filesystem such as OverlayFS and adds a thin writable layer on top for the container.

Every component is identified by a content digest, a SHA-256 hash of its bytes. Because identity is derived from content, two images that share a base layer store it only once, and a reference by digest is guaranteed to retrieve exactly the same bits every time.

ComponentContentPurpose
LayersCompressed archives of file changesBuild the root filesystem
Image configurationCommand, environment, user, ports, historyTells the runtime how to start the container
ManifestDigests and sizes of layers and configurationDescribes one image for one platform
Image indexList of manifests per architectureEnables multi-platform images
TagHuman-readable name pointing to a manifestConvenient but mutable reference
Components of an OCI container image

How images are built and distributed

Images are usually built from a Dockerfile or a similar recipe. Each instruction that changes files, such as copying source code or installing packages, produces a new layer, and the builder caches layers so that unchanged steps are reused. Ordering instructions from least to most frequently changing keeps rebuilds fast.

Multi-stage builds separate the build environment from the final image. Compilers and build tools live in an early stage, and only the resulting binaries or files are copied into a small runtime stage. Finished images are pushed to a container registry, from which hosts pull only the layers they do not already have.

Base image typeTypical compressed sizeTrade-off
Full distributionRoughly 30 to 80 MBFamiliar tools, larger attack surface
Slim variantRoughly 20 to 40 MBFewer packages, still a shell and package manager
Alpine-basedA few megabytesVery small, uses musl instead of glibc
Distroless or scratchFrom zero to a few megabytesMinimal surface, harder to debug
Common base image choices

The image sits in the middle of the container workflow, between the recipe that defines it and the running process created from it. Clear boundaries help explain where a change must be made.

ConceptWhat it isRelation to the image
DockerfileBuild instructionsProduces the image
ContainerRunning instance with a writable layerCreated from the image
Container registryStorage and distribution serviceHolds and serves images
Docker ComposeMulti-container definitionReferences images by name
VM imageFull disk with its own kernelHeavier; container images share the host kernel
The image and its neighbors in the container workflow

Because a container image does not include a kernel, it relies on the host kernel. A Linux image runs on a Linux kernel, and the image’s CPU architecture must match the host unless emulation is used, which is why multi-architecture images for amd64 and arm64 have become standard.

Building good images in practice

A good image is small, reproducible, secure and free of secrets. These qualities reduce pull time, attack surface and the risk of leaking credentials, and they make deployments predictable across environments.

PracticeEffectCommon mistake it prevents
Multi-stage buildsRemoves build tools from the final imageShipping compilers to production
Pinning by digestDeploys exactly the tested imageA tag silently pointing to new content
Non-root userLimits damage after a compromiseContainers running as root by default
Secrets at run timeKeeps credentials out of layersKeys recoverable from image history
Regular rebuilds and scansPicks up security patchesOutdated libraries with known flaws
Image practices and their effect
  • Use a .dockerignore file so local files, logs and credentials never enter the build context.
  • Combine package installation and cache cleanup in one layer, because files deleted in a later layer still occupy space.
  • Label images with version and source revision to support traceability.

Pitfalls and misconceptions

A frequent misconception is that the latest tag means the newest image. It is only a default name that can point to anything, so production deployments should reference a specific version or digest. Another is that deleting a file in a later instruction removes it from the image; it only hides it, and the data remains in the earlier layer.

Images also age without changing. An image built a year ago may contain dozens of known vulnerabilities in its base packages even though its own code is unchanged, so a regular rebuild and redeploy cycle belongs to normal operations.

The short version

A container image is like a sealed meal kit. It contains every ingredient and the exact recipe needed to make one dish, packed so that it comes out the same in any kitchen.

The kit itself never changes. Each time someone cooks from it, they get a fresh meal, which is the running container. Build once, run the same way everywhere is the whole idea, and it removes the old problem of software working on one computer but not on another.

Where it makes a difference

A development team ships a web API written in Go. Their first image was built on a full distribution base and weighed about 900 MB, including the compiler, test tools and a copy of the local configuration file. Deployments to new servers took several minutes, mostly spent pulling the image.

The team switched to a multi-stage build: the first stage compiles the program, and the final stage copies only the binary and certificates into a distroless base, running as a non-root user. The new image is about 25 MB, starts in seconds, and contains no shell or package manager. Production now references images by digest, and a weekly pipeline rebuilds them so that base image security fixes reach production without manual work.