Skip to content

🐳 Mastering Docker Images: The Comprehensive Guide¢

image

The Image Concept: Blueprints for RuntimeΒΆ

A Docker image is a read-only, immutable package containing everything required to run an application: code, runtime, system libraries, environment variables, and config files.

The Build-Time vs. Run-Time DistinctionΒΆ

  • Image (Build-Time): A static blueprint stored on disk.
  • Container (Run-Time): A dynamic, living instance of an image.
  • Relationship: You can instantiate multiple containers from a single image. Once a container is running, it is "bound" to its parent image. You cannot delete an image while containers (even stopped ones) are still referencing it.

image

The "No Kernel" ArchitectureΒΆ

Images are remarkably small because they lack an OS Kernel.

  • Containers share the Host OS Kernel (Linux or the lightweight utility VM on Windows/macOS).
  • The only OS-related components in an image are Filesystem objects (bins, libs, configs).

ImmutabilityΒΆ

Once an image is created, it cannot be changed. Updates are made by creating a new image with a new version tag or digest.

Image Anatomy and LayeringΒΆ

Docker creates images by stacking independent, read-only layers. This "stack" is presented as a single, unified object through a Union File System (UnionFS).

image

  • Efficiency through Sharing: If multiple images share a base layer (e.g., alpine), Docker only stores and pulls that layer once.
  • Layer Composition: Every command in a Dockerfile (like RUN, COPY, ADD) creates a new layer.
  • Copy-on-Write (CoW): When a container starts, Docker adds a thin Writable Layer on top of the image. Any changes made during execution are stored here, leaving the underlying image pristine.
Component Description
Base Layer Usually a minimal OS (e.g., Alpine, Ubuntu). All images start here.
Stacked Layers Each instruction in a Dockerfile (RUN, COPY, ADD) creates a new layer.
Layer Sharing Docker uses Content-Addressable Storage. If two images use the same base layer, Docker only stores one copy on disk.
Copy-on-Write (CoW) When a container starts, Docker adds a thin Writable Layer on top. Changes are written here, while the underlying image layers remain untouched.

image

The Storage Driver & Filesystem AbstractionΒΆ

Docker uses storage drivers to stack these layers and present them as a unified filesystem.

image

  • The Industry Standard: Almost all modern Docker setups use the overlay2 driver.
  • Alternative Options: Depending on the host OS and requirements, Docker also supports zfs, btrfs, and vfs.
  • The Abstraction Layer: Regardless of which storage driver is used (the "how"), the developer and user experience remain identical (the "what"). The driver handles the complexity of merging layers into a single file tree seamlessly.

Storage and RegistriesΒΆ

The Local Repository (Image Cache)ΒΆ

  • Linux: Typically found at /var/lib/docker/<storage-driver> (usually overlay2).
  • Desktop: Stored within the managed Docker Desktop VM.
  • Mechanics: Pulling an image checks your local cache first. Docker only downloads layers that are missing from your local repository.

Image RegistriesΒΆ

Registries are centralized warehouses for images.

image

  • OCI Compliance: Modern registries implement the OCI Distribution-Spec, ensuring interoperability across different container engines.

  • Official vs. Unofficial:

    • Official: Curated and vetted by Docker and vendors (e.g., redis, nginx). They reside at the root of the Docker Hub namespace.
    • Unofficial: User-contributed. They require a prefix: username/repository.

Naming and TaggingΒΆ

Naming ConventionΒΆ

image

A fully qualified image name follows this structure: [REGISTRY_HOST]/[ORG_OR_USER]/[REPOSITORY]:[TAG]

  • Default Registry: docker.io (Docker Hub).
  • Default Tag: latest.
  • Official Repos: These live in the top-level namespace (e.g., redis, nginx, alpine) and are vetted for security.
# Pulling from a custom registry (GitHub Container Registry)
docker pull ghcr.io/username/app-name:v1.2.0

[!WARNING] The latest Tag Trap: The latest tag is just a default label. It is mutable, meaning the image it points to can change. In production, always use specific version tags or digests for reproducibility.

Image Inspection and HistoryΒΆ

docker image inspectΒΆ

Provides the full JSON metadata of an image, including the RootFS (a list of all layer SHA256 hashes). Shows high-level metadata (Architecture, OS, Config, Environment variables).

docker image inspect <IMAGE_ID>

docker historyΒΆ

Shows how the image was built.

  • Metadata Instructions: Commands like ENV, EXPOSE, and CMD add metadata but create 0B layers.
  • Filesystem Instructions: RUN, COPY, and ADD create layers that consume disk space.

Note: In 2026, many layers in docker history appear as <missing>. This is normal; it simply means those layers were built on a different machine (e.g., the official build server) and are not individually manageable on your local host.

Immutability via DigestsΒΆ

Tags are "pointers" and can be changed. Digests are cryptographic SHA256 hashes of the image's content.

  • Content-Addressable Storage: If the content of an image changes, its digest must change.
  • Pulling by Digest: For maximum security (preventing "Tag Poisoning"), pull images by digest to ensure you get the exact bits you tested.
docker pull alpine@sha256:5b10f432ef3da1b8d4c7eb6c487f2f5a8f096bc91145e68878dd4a5019afde11

Distribution vs. Content HashesΒΆ

To save bandwidth, Docker compresses images during transport.

  1. Distribution Hash: The hash of the compressed layer data (checked during pull/push) used during transport to ensure no tampering occurred.
  2. Content Hash: The hash of the uncompressed layer data (used by the storage driver).

Multi-Architecture ImagesΒΆ

The modern web runs on amd64 (Intel/AMD) and arm64 (Apple Silicon, AWS Graviton). Docker uses Manifest Lists to hide multiple architectures behind a single tag.

  1. Manifest List (or Index): A high-level list of which architectures an image supports.
  2. Manifest: The specific blueprint for a specific architecture.

image

The Workflow: When you docker pull, the Docker Engine checks your local CPU architecture, looks at the Registry's Manifest List, and automatically pulls the correct binary for your system.

Creating Multi-Arch Images with BuildxΒΆ

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t username/app:v1 --push .
  • Emulation (QEMU): Slow, runs target architecture in a VM.
  • Build Cloud: Uses native cloud hardware; significantly faster and provides a shared cache for teams.

Security: Vulnerability ScanningΒΆ

Docker Scout is the current industry standard for supply chain security, replacing legacy scanning tools.

  • Quickview: docker scout quickview gives an instant risk assessment.
  • CVES: docker scout cves provides deep analysis and remediation advice (e.g., "Upgrade base image from Python 3.11-alpine to 3.14-alpine").
  • Policy Evaluation: Can block images from being pushed if they contain critical vulnerabilities.
docker scout quickview <image_name>

Maintenance and DeletionΒΆ

Removing Images (rmi)ΒΆ

Use docker rmi to remove images by Name, ID, or Digest.

  • Dangling Images: Images with no tags (result of a new build using an existing tag). Clean them using docker image prune.
  • Shared Layers: Docker won't delete the actual layer files until the last image referencing them is removed.

Bulk DeletionΒΆ

To purge all local images (use with extreme caution):

# Force delete all local images (Use with caution!)
docker rmi $(docker images -q) -f

Note: The -f (force) flag should be avoided if possible. Forcing deletion of an image in use by a container creates a "dangling" image state where the tag is removed but the data remains.

Managing the LifecycleΒΆ

  • List Images: docker image ls (or docker images). Use --digests to see SHA hashes.
  • Remove Image: docker rmi <ID_or_Name>.
    • Docker won't delete a layer if it's still being used by another image.
    • You cannot delete an image used by a running (or stopped) container.
  • Cleanup: docker image prune removes "dangling" images (images with no tags). docker system prune -a is the "nuclear" option to clean all unused images.

Comments