CodeOath
← All posts
Docker65 min total · 19 parts

Docker Fundamentals: Images, Containers, and Writing a Good Dockerfile

Contents — Part 2 of 19: What Problem Docker Actually Solves
Part 2 of 19 · ~2 min

What Problem Docker Actually Solves

Before containers, "it works on my machine" was a real, constant problem. An application depends on a specific language runtime version, a set of system libraries, particular environment variables, maybe a specific OS-level package — and getting all of that to match exactly between a developer's laptop, a CI runner, and a production server was mostly manual, error-prone work (README files full of setup steps, configuration management tools, or just tribal knowledge).

Docker's answer is to package the application and its entire runtime environment into a single artifact — an image — that runs identically anywhere Docker itself runs. The host machine's OS, installed packages, and configuration stop mattering, because the container brings its own.

This is easy to confuse with virtual machines, which solve a similar-sounding problem very differently:

Virtual MachineContainer
What it virtualizesEntire hardware, including its own kernelJust the process — shares the host's kernel
Startup timeSeconds to minutes (boots a full OS)Milliseconds to a few seconds
SizeGigabytes (a full OS image)Megabytes to a few hundred MB, typically
Isolation strengthVery strong — separate kernel entirelyWeaker — isolated via kernel namespaces/cgroups, not a separate kernel
Density per hostLow — each VM carries full OS overheadHigh — many containers can share one kernel cheaply

A container is not a "lightweight VM" — it's a normal process on the host, made to look isolated using two Linux kernel features: namespaces (which give a process its own view of the process tree, network interfaces, filesystem mounts, and hostname, so it can't see or interfere with anything outside it) and cgroups (which cap and account for the CPU, memory, and I/O that process is allowed to use). There is no hypervisor and no second kernel — which is exactly why containers start so much faster and cost so much less overhead than a VM, but also why they isolate less strongly. A kernel-level exploit that escapes a container's namespace can reach the host in a way that a VM's separate kernel would generally block.