Docker is a platform for building, shipping and running applications inside containers. A container is not a lightweight virtual machine — it is an ordinary Linux process, isolated by kernel features that already existed: namespaces partition what a process can see, cgroups limit what it can consume, and capabilities restrict what it is permitted to do. Docker packages those primitives behind a workflow that a developer can use without knowing they are there.
The artefact at the centre of that workflow is the image: a stack of read-only filesystem layers plus metadata describing how to start a process. Because layers are content-addressed and cached, rebuilding an image after a small change is fast, and because the image includes its dependencies, the thing tested is the thing deployed. Registries — Docker Hub, Artifactory, Nexus, ECR, ACR — move those images between build and runtime.
Around that core sit the pieces production needs: volumes and bind mounts for state, six network drivers for connectivity, Compose for multi-container definitions, and the runtime layer beneath Docker itself — dockerd, containerd, CRI-O and runc — which matters increasingly as Kubernetes clusters use containerd directly. Understanding where Docker ends and the runtime begins is what makes container problems debuggable.
Why this skill matters now
Containers stopped being a differentiator and became the default packaging format for server-side software. CI systems build images, registries store them, and orchestrators run them — so container literacy is now assumed across development, platform and operations roles rather than being a specialism.
What has changed is the depth expected. Writing a Dockerfile that works is straightforward; writing one that produces a small, reproducible, non-root image with sensible layer caching and a multi-stage build is a different skill, and it is the one that shows up in image-scanning reports and cloud bills. Equally, teams increasingly need to reason about the runtime layer, because Kubernetes talks to containerd rather than to Docker, and the distinction surfaces the moment something misbehaves.
Docker also remains the entry point to everything above it. Kubernetes, service meshes and CI pipelines all assume container fluency, so weak fundamentals here produce confusion that compounds later.