Mechanism 03Containers and InfrastructureInteractive · 6 min

What actually happens when you type docker run?

No virtual machine boots. Docker downloads the layers it's missing, stacks them into a filesystem, and asks the Linux kernel to start one ordinary process that can only see what it's been given.

All timings on this page are illustrative. They show where the time goes, not what your machine will do.

Nothing is on this machine yet. Before anything can start, the daemon downloads every layer of the image. Then starting the container itself is quick.

ReadyRun the image and follow the command through each part.

Ready. Run the image and follow the command through each part.

step 1/1
Image
Inside the newest container
For new containers
Layersstruck through = not on this machine
layermade bysizein
a1f3FROM node:22-slim74 MB1.0 1.1 1.2
b7c2RUN npm ci41 MB1.0 1.1
c9e0COPY . .2 MB1.0
c4d8COPY . .2 MB1.1
e5a1RUN npm ci46 MB1.2
c2b6COPY . .2 MB1.2
Counters
0MB downloaded
0Layers reused
0Containers started
0OOM kills
Containers⛁ = named volume mounted

(no containers)

Sheet 03 · docker run, from command to processOne host, one registryTimings illustrative
The model

Three ideas explain most of it

Idea 1

An image is a stack of layers

Each instruction in a Dockerfile that changes files makes one read-only layer, named by a hash of its content. Two images that share a base share those bytes on disk and over the network.

Idea 2

A container is a process

Namespaces give it a private view of process IDs, mounts and the network. A cgroup caps its memory and CPU. Underneath, it's one more process on the host's kernel.

Idea 3

Its changes are disposable

Each container gets a thin writable layer on top of the image. Whatever it writes there disappears with it. Data that must outlive a container goes in a volume.

Under the hood

A Dockerfile is a list of layers

Live: the line that made this layerDockerfile

FROM node:22-slimWORKDIR /appCOPY package*.json ./RUN npm ci --omit=devCOPY . .CMD ["node", "server.js"]

Live: the terminal

(nothing run yet)

$ docker ps -a
CONTAINER  IMAGE     STATUS              HOST PID  MEM

Read the Dockerfile from the top. FROM brings in someone else's layers, here a slim Debian with Node installed. Each RUN and COPY adds one more.

The order is deliberate. Dependencies change rarely and weigh a lot, so package.json is copied and installed first. Application code changes on every commit and weighs little, so it goes last. A change invalidates its own layer and every one above it, never the ones below.

The host PID column shows the other half. Inside, the server is PID 1 and sees no other processes. Run ps on the host and it's there like any other program. Containers isolate processes. They don't virtualise hardware.

When it breaks

Most surprises are one of these

Scenario D · exit 137

The kernel kills it, not Docker

Go over a cgroup's memory limit and the kernel's OOM killer sends SIGKILL. There's no exception to catch and no log line from your app. 137 means 128 + signal 9.

Scenario E · missing data

The database was in the container

Removing and re-creating a container is routine: upgrades do it. Anything in the writable layer goes with it. Restarting keeps it, which is why the bug can hide for weeks.

Scenario C · slow deploys

Every deploy downloads everything

Usually a Dockerfile copying the code before installing dependencies, or a base image tag that moves. Both make layers that could be shared look new.

Test yourself

Two predictions

A server already runs web:1.0. You change one line of server.js, build web:1.1 and run it there. How much does the server download?

Now the Dockerfile is reordered: COPY . . comes before RUN npm ci. Every code change still edits only server.js. What happens to the npm ci layer?

Fine print

What this model leaves out

Building images

Every image here already exists in the registry. docker build runs each instruction in a temporary container and snapshots the result as a layer, using the same rule for its cache: a layer is reused only if its instruction and everything below it are unchanged.

Downloads, compression and digests

Layers are compressed tarballs, fetched several at a time, and the ids here stand in for full sha256 digests. Unpacked sizes on disk are larger than what crosses the network.

Networking, users and security

Containers also get a network namespace with its own interfaces, usually bridged to the host. Real isolation also leans on dropped capabilities, seccomp filters and user namespaces, none of which are modelled.

Docker Desktop on a Mac or Windows

Containers need a Linux kernel, so Docker Desktop runs one in a small virtual machine and your containers run inside it. On a Linux server there's no VM at all, which is what this page shows.

Keep going

Connected mechanisms