A container is a process, not a machine
If you arrived here from Linux, take this translation first: a running container is an
ordinary process on your kernel. No guest OS, no hypervisor. The kernel gives it
namespaces so it sees its own PID tree, mounts, network and hostname, and
cgroups so its CPU and memory can be capped. ps on the host
lists it. kill on the host kills it. Podman leans into that: no
daemon sits in the middle - the container is a child of your own shell, and rootless mode
maps your user onto root inside the container through a user namespace, so root in
there is an unprivileged UID out here.
So what does the image provide? The filesystem that process sees. That is the whole
job, and it is why an image is a stack of layers rather than a disk image.
Field note. Prove it on your own box.
podman run -d --name t alpine sleep 300, then on the
host: ps -ef | grep sleep finds the process,
lsns -p <pid> lists the namespaces it was handed,
cat /proc/<pid>/cgroup shows where its limits live, and
mount | grep overlay shows the layers stitched together. None of
it is exotic. It is your kernel, described differently.
What an image is made of
An image is not a copy of a machine. It is a stack of read-only layers, each
recording only what changed from the one beneath. Layers are content-addressed, so an
identical layer is stored once and reused by every image that references it, so a pull
fetches just the layers you do not already have. A base sits at the bottom, your dependencies on it,
your code - usually the smallest layer, and typically the most volatile - above that.
Those layers become one filesystem through a union mount - overlayfs, the same
kernel feature you can mount by hand. The read-only image layers are the lower dirs; the
container gets a fresh upper dir of its own. Writes land in the upper, and editing an
existing file copies it up there first, leaving the image layer untouched underneath.
That upper dir is the top slab in the scene, and it is the odd one out: the writable
layer is not part of the image. The runtime creates it with the container and
discards it when that container dies. Nothing written there ships, and nothing written there
survives, which is the entire reason volumes exist.
Change a layer and every layer above it must be rebuilt.
The order is a caching decision
The builder caches layer by layer, and a cached layer survives only while everything
beneath it is unchanged. Put COPY . . above your dependency
install and you have told the builder to throw the dependency cache away every time one
line of code changes. Dependencies first, code last - a Containerfile is a cache policy that
happens to build software.
Field note. A rebuild that takes twenty minutes and one that
takes twenty seconds are usually the same Containerfile with the lines swapped.
This stack explains a lot of what sits above it: shared layers make
pulls fast, immutable content lets a digest name exact bytes (Course VII), and the throwaway
top layer is why persistent state needs volumes.
Pre-reads: none - start here
Further: Podman get-started ·
Podman docs + builds