Session 3 · Images, containers and registries#
The big idea#
An image is a read-only template: files plus the instructions to start a program. A container is a running (or stopped) instance made from an image. You can start many containers from one image, and each gets its own private, writable layer.
Everyday example: a bakery. The recipe and dough is the image: you can’t eat it, and it never changes. The cookies you bake are containers. Bake ten cookies from one recipe; eating or breaking one doesn’t change the recipe or the other cookies. The registry is the recipe shop where bakeries buy and share recipes.
One image, several containers#
docker rm -f dm-a dm-b >/dev/null 2>&1
echo '--- one image, two containers'
docker create --name dm-a alpine echo "container A" >/dev/null
docker create --name dm-b alpine echo "container B" >/dev/null
docker ps -a --filter name=dm- --format '{{.Names}} {{.Image}} {{.Status}}' | sort
echo '--- start them'
docker start -a dm-a
docker start -a dm-b
echo '--- changes live in the container, not in the image'
docker run --name dm-a2 alpine sh -c 'echo secret > /note.txt && cat /note.txt'
docker run --rm alpine cat /note.txt 2>&1 | sed 's/^/new container: /'
echo '--- the layers an image is built from'
docker history alpine:3.20 --format '{{.CreatedBy}} {{.Size}}'
docker rm -f dm-a dm-b dm-a2 >/dev/null
--- one image, two containers
dm-a alpine Created
dm-b alpine Created
--- start them
container A
container B
--- changes live in the container, not in the image
secret
new container: cat: can't open '/note.txt': No such file or directory
--- the layers an image is built from
CMD ["/bin/sh"] 0B
ADD alpine-minirootfs-3.20.10-x86_64.tar.gz … 7.81MB
What to take from it:
docker createmakes two containers (dm-a,dm-b) from the same image. They areCreated, not running.docker start -aruns each one and shows its output.A file written in one container (
/note.txt) is gone in a brand-new container from the same image. Changes belong to the container’s writable layer, not the image.docker historylists the layers: a tiny Alpine root filesystem (7.81MB) plus a start command (CMD ["/bin/sh"], 0 bytes). Images are stacks of layers, and identical layers are shared between images.
Where images come from#
Images reach your machine in two ways. You pull one that someone else published (docker pull nginx:alpine), or you build your own from a Dockerfile (Session 7). Either way it is stored locally
as layers. When you docker run a name you don’t have, Docker pulls it for you first. That is why the
first run of a new image is slow and the second is instant.
A tag such as 3.20 or alpine is just a label pointing at one image. The same image can have several
tags, and a tag can later be moved to a newer image. If you need something exact, you can name an image by
its digest (alpine@sha256:...), which never changes.
Useful commands for this session#
Command |
What it does |
|---|---|
|
Download an image from the registry |
|
List local images |
|
Running containers / all containers |
|
Delete a container |
|
Delete an image (no container may use it) |
|
Show an image’s layers |
Common mistakes#
Mixing up image and container. Deleting a container does not delete the image, and an image can’t “run”; you run a container made from it.
Saving data inside a container. It disappears with the container (Session 8 fixes this).
Piling up stopped containers.
docker ps -ashows them all. Use--rmfor throwaway runs, ordocker container pruneto clear stopped ones.Trying to remove an image that a container still uses. Remove the container first.
Thinking
docker pullupdates running containers. It only fetches the new image. Recreate the container to use it.
Hands-on exercises#
Exercise 1. Create two containers from alpine that each print their own name, run both, and
remove them.
Solution
docker create --name one alpine echo "I am one"
docker create --name two alpine echo "I am two"
docker start -a one
docker start -a two
docker rm one two
Each start -a prints that container’s line. The image is shared; the containers are separate.
Exercise 2. Prove that a file created in one container is not visible in another.
Solution
docker run --name first alpine sh -c 'echo hi > /x.txt'
docker run --rm alpine cat /x.txt
docker rm first
The second command fails with cat: can't open '/x.txt': No such file or directory.
Exercise 3. How many layers does alpine:3.20 have, and which one is the largest?
Solution
docker history alpine:3.20 --format '{{.CreatedBy}} {{.Size}}'
On this machine it shows two entries: the CMD line (0B) and the root filesystem ADD (7.81MB), which is
the largest.
Practice#
Take the Session 3 quiz. The original bakery story is in the reference section.