Docker's Historical Role
Docker didn't invent containers. Linux Containers (LXC) existed since 2008, and the underlying primitives — namespaces and cgroups — are even older. What Docker did in 2013 was make containers usable.
Three key things Docker introduced:
- Dockerfile — a declarative, human-readable recipe for building images
- Image format — layered, content-addressable images that cache efficiently
- Registry model — Docker Hub as a universal distribution hub (
docker pull nginx)
These three things together created the "write once, run anywhere" developer experience that made containers mainstream.
OCI Standards
Docker's success created a problem: every tool was tightly coupled to Docker's proprietary formats. In 2015, Docker, CoreOS, and others founded the Open Container Initiative (OCI) under the Linux Foundation to define vendor-neutral standards.
OCI produced two specifications:
- Runtime Spec — defines how a container process is started, stopped, and managed (implemented by
runc,crun) - Image Spec — defines the image layer format, manifest, and config so images work across any OCI-compliant runtime
Why does this matter? Any tool that builds or runs an OCI image works with any OCI runtime. Build with Buildah, run with containerd, push to Quay. No lock-in.
Quiz 1: What was the primary motivation for founding the Open Container Initiative (OCI) in 2015?
The Runtime Layer
Container runtimes split into two levels:
- Low-level runtimes implement the OCI Runtime Spec. They talk directly to the kernel — setting up namespaces, cgroups, and starting the process. Examples:
runc(written in Go, the reference impl),crun(written in C, faster startup). - High-level runtimes sit above low-level runtimes and add image management, networking, storage, and a gRPC API for orchestrators. Examples:
containerd,CRI-O.
Docker's Architecture
When you type docker run nginx, more is happening than meets the eye. Docker is actually a layered stack of components:
docker run traverses this entire stack.Key insight: dockerd and containerd are separable. Kubernetes speaks directly to containerd (via CRI) and doesn't need dockerd at all — which is why Kubernetes dropped dockershim support in 2022.
For years, Kubernetes used a shim layer (dockershim) to talk to Docker, which internally called containerd. In Kubernetes 1.24 (2022), the shim was removed. Kubernetes now talks directly to containerd or CRI-O via the Container Runtime Interface (CRI).
What this means for you: if your cluster used Docker as its runtime, you migrated to containerd. If you were just building images with Docker — nothing changed. Docker images are OCI images; they run everywhere.
Alternatives to Docker
| Feature | Docker | Podman |
|---|---|---|
| Architecture | Client + daemon (dockerd) | Daemonless — fork/exec model |
| Root required? | Yes (daemon runs as root) | No — rootless by default |
| CLI compatibility | docker CLI | Drop-in alias: alias docker=podman |
| Pods support | No native pods | Yes — Kubernetes-compatible pod model |
| Best for | Developer workflows, Compose | CI security, enterprise Linux |
Other notable alternatives in the developer toolchain:
- nerdctl — a Docker-compatible CLI for containerd; supports Compose, feels like Docker, no daemon required
- Buildah — builds OCI images without a daemon, scriptable, great for rootless CI pipelines
- Skopeo — inspects and copies images between registries without ever pulling them locally; ideal for mirroring and signing workflows
Quiz 2: What is the key architectural difference between Docker and Podman?
The Bigger Ecosystem
Containers don't live in isolation. Three categories complete the picture:
Registries
Registries store and distribute OCI images. All are interoperable — an image pushed to one can usually be pulled by any client.
- Docker Hub — the original public registry; home to official images
- GHCR (GitHub Container Registry) — tightly integrated with GitHub Actions
- Quay.io — Red Hat's registry; strong on security scanning
- Harbor — self-hosted, open-source; adds RBAC, replication, and image signing
Orchestrators
Running one container on your laptop is easy. Running thousands across a fleet requires an orchestrator:
- Kubernetes (K8s) — the industry standard; large surface area but unmatched ecosystem
- Docker Swarm — simpler, built into Docker; adequate for smaller deployments
- HashiCorp Nomad — polyglot scheduler; runs containers, VMs, and raw executables
Build Tools
- BuildKit — the modern Docker build engine; parallel stages, cache mounts, secrets
- Kaniko — builds Dockerfile-based images inside Kubernetes, no Docker daemon
- Cloud Native Buildpacks — detect your language, build an OCI image with no Dockerfile at all
Quiz 3: You need to build OCI images inside a Kubernetes cluster as part of a CI pipeline, with no Docker daemon available. Which tool is designed for this use case?
🎯 Key Takeaways
- Docker democratized containers (2013) via Dockerfile, layered images, and Docker Hub — not by inventing the underlying tech.
- OCI (2015) standardized the image and runtime specs, breaking vendor lock-in and enabling a rich ecosystem.
- Two runtime tiers: low-level (runc, crun) implement the OS primitives; high-level (containerd, CRI-O) add image management and orchestrator APIs.
- Docker's stack is CLI → dockerd → containerd → runc → container. Kubernetes bypasses dockerd entirely.
- Podman is a compelling Docker alternative: daemonless, rootless, and CLI-compatible.
- The ecosystem extends far beyond the runtime: registries, orchestrators, and build tools each have multiple OCI-compatible options.