sehaj/learn
Docker/01 Foundations

01.04 · with code · 12 min

Images, containers, registries

The three nouns of Docker, how they relate, and how to read an image name like ghcr.io/sehaj/api:1.2.0.

The core idea

Almost everything in Docker is one of three things:

  • An image is a read-only template: a stack of filesystem layers plus settings like which command to run.
  • A container is a running (or stopped) instance of an image, with a thin writable layer of its own on top.
  • A registry is a server that stores images so you can push and pull them, like Docker Hub or GitHub's GHCR.

If you write code, a familiar comparison helps: an image is like a class and a container is like an object. You can create many containers from one image, and changing one container doesn't change the image or its siblings.

Images: layers plus settings

An image has two parts:

  • Layers: read-only snapshots of files. Each step of a Dockerfile that changes files adds one (02.02 Layers and the build cache).
  • Config: environment variables, the working directory, the default command, exposed ports.

Every image has a digest, a SHA-256 hash of its contents. When this lesson was written, nginx:alpine had the digest sha256:785835ea65db4bba6f021acc0f3be91b0fef76a53fe41f8588c6698d2aed0606. Change one byte and the digest changes. That makes it the only name that always means exactly the same image.

Containers: an image plus a writable layer

When you start a container, Docker stacks a small writable layer on top of the image's read-only layers. Anything the container writes, creates or deletes goes into that layer. The image underneath never changes.

Two containers, one image
Container one
writable layer (one)
image layer 3
image layer 2
image layer 1
Container two
writable layer (two)
image layer 3
image layer 2
image layer 1
The image layers are stored once and shared. Each container only adds its own thin writable layer.

This is why starting a container is nearly instant and nearly free on disk: nothing is copied. It's also why the writable layer is temporary. Delete the container and its changes are gone, unless they were in a volume (04.01 The writable layer is temporary).

Predict first

Containers one and two both run from nginx:alpine. Inside one, you create /tmp/hello.txt. Can two see it?

Commit to an answer before you read on.

Registries and image names

A registry stores images in repositories, and each repository holds many tags. A full image name tells Docker exactly where to look:

Reading an image name
ghcr.ioregistry
/
sehaj/apirepository
:
1.2.0tag
Leave out the registry and Docker assumes Docker Hub. Leave out the tag and it assumes latest.

So the short name you type most often expands to something longer:

You typeDocker reads it as
nginxdocker.io/library/nginx:latest
node:22-slimdocker.io/library/node:22-slim
ghcr.io/sehaj/api:1.2.0exactly that
nginx@sha256:785835ea…that exact image, by digest

Tags are movable labels. nginx:1.27 today may point at a different image next month after a patch release. Digests never move. That's why production deploys often pin by digest; more in 02.06 Tags, digests and registries.

See it yourself

CheckpointTwo containers, one image, separate changes

Start two containers from the same image, write a file in one, and ask Docker what changed in each.

❯terminal
$ docker run -d --name one nginx:alpine
$ docker run -d --name two nginx:alpine
$ docker exec one sh -c 'echo hi > /tmp/hello.txt'
$ docker diff one
C /run
A /run/nginx.pid
...
C /tmp
A /tmp/hello.txt
...
$ docker diff two
C /etc
C /etc/nginx
...
A /run/nginx.pid

Output trimmed. A means added, C changed, D deleted. Both list files nginx wrote when it started, but only one has your new file. Clean up with docker rm -f one two.

STUCK? ▸

Both containers show changes under /etc/nginx, /run and /var/cache/nginx: that's nginx itself writing at startup. Only one should list /tmp/hello.txt. Container names must be at least two characters, which is why these aren't called a and b.

Recap

Interview questions

JuniorfreqMust-knowConcept

What is the difference between a Docker image and a container?

MidfreqMust-knowScenario

Why would you deploy an image by digest instead of by tag?

Report a mistakeEdit this page