Docker is not a container. Docker is a set of tools for building, shipping, and running containers — and the distinction matters, because the container is a kernel feature and Docker is the ergonomics wrapped around it.
If you have taken Containers From Scratch, you have already built one by hand: namespaces, cgroups, a copy-on-write filesystem, nine commands. This course is the other direction. Everything here is what those nine commands became once someone made them pleasant to use.
Running docker run involves four things, and knowing which is which saves a lot of confused debugging:
| Piece | What it is |
|---|---|
| The CLI | the docker command you type. It talks to the daemon over a socket, and can talk to a daemon on another machine. |
The daemon (dockerd) | the long-running process that actually does the work. Holds your images, containers, networks, volumes. |
| containerd + runc | what the daemon delegates to. containerd manages container lifecycle; runc is the thing that actually calls the kernel. |
| A registry | where images live when they are not on your machine. Docker Hub by default. |
This one is a recording — the commands are real, but nothing is running here. Type them into your own shell to follow along.
Read what that second command actually did. The image was not present, so the CLI asked the daemon, the daemon pulled it from Docker Hub, unpacked it, created a container from it, ran it, and the container exited. --rm then deleted the container. Five distinct operations behind one word.
You run a Docker command and get "Cannot connect to the Docker daemon". What does that tell you?
This is the single most useful distinction in Docker, and it is worth being pedantic about because almost every confusing error message depends on it.
An image is a read-only stack of filesystem layers plus metadata saying what to run. It is inert. It is a template.
A container is a running (or stopped) instance of an image, with a thin writable layer on top. You can create fifty containers from one image; they share every byte of the image and differ only in what they have written.
docker images # the templates you have
docker ps # the running instances
docker ps -a # ...including the stopped ones
The relationship is exactly class-and-object, or program-and-process. docker rmi deletes a template; docker rm deletes an instance. Deleting an image that a container still uses fails, for the same reason you cannot delete a program's binary out from under a running process.
You edit a file inside a running container, then stop it and start a fresh container from the same image. Is your edit there?
Worth stating plainly because the intuition points the wrong way: a Linux container shares the host's kernel. There is no guest operating system inside an image and no hypervisor underneath.
That is why an Alpine image is eight megabytes — it contains a userland, not an OS. It is why a container starts in milliseconds instead of the tens of seconds a VM takes. And it is why Docker on macOS and Windows runs a Linux VM in the background: Linux containers need a Linux kernel, so if the host has not got one, one is provided.
Docker Engine 29.0 changed a default that had been in place for a decade: the containerd image store is now the default on fresh installations, replacing the legacy graph drivers.
This is mostly invisible, and where it is visible it is an improvement:
docker image save and docker image load now take --platform and understand multiple platforms.docker image ls looks different. What used to be --tree is the default view, and untagged images are no longer listed unless you pass --all.An existing installation that upgraded keeps its old store — the change is for fresh installs. docker info tells you which you have, under the storage driver line. And one carve-out worth knowing: daemons using userns-remap do not get the containerd store, because of an unresolved interaction between the two.
Everything in this course is written against specific versions, listed on the course page. Confirm yours before you start wondering why a flag does not exist:
This one is a recording — the commands are real, but nothing is running here. Type them into your own shell to follow along.
Note docker compose, two words. docker-compose with a hyphen was the original Python implementation; it reached end of life in July 2023 and is not what you want. If a tutorial you are reading uses the hyphen, it predates a great deal of what this course covers — which is a useful signal in its own right.
Show the currently running containers.
Next up: running containers — the flags that make up 90% of what anyone types at a Docker prompt.
