Skip to main content

How Docker Works Under the Hood

Watch what really happens when you run docker run -p 8080:80 nginx, one layer at a time. Step down the whole stack: the CLI, the daemon, the registry pull, containerd, the OCI runtime bundle, runc, the running container, and the shared Linux kernel. Every stage shows the real low-level command you can run yourself, so it doubles as a tour of the primitives that make a container: namespaces, cgroups, and runc. A container is not a small VM, and this shows you why.

Category: DevOps

What You Will Learn

  • What actually happens when you run docker run -p 8080:80 nginx, layer by layer
  • Why the docker CLI is just a REST client that talks to the daemon over a socket
  • How dockerd delegates to containerd, and what containerd does with the image layers
  • What an OCI runtime bundle is: a config.json plus a rootfs
  • How runc turns that bundle into a running process using namespaces and cgroups
  • Why a container is a normal host process, not a small virtual machine

Topics covered: docker, containers, containerd, runc, namespaces, cgroups, oci, linux, kernel, devops, interactive, educational

// simulator

How Docker Works Under the Hood

Watch what really happens when you run docker run -p 8080:80 nginx, one layer at a time. Step down the whole stack: the CLI, the daemon, the registry pull, containerd, the OCI runtime bundle, runc, the running container, and the shared Linux kernel. Every stage shows the real low-level command you can run yourself, so it doubles as a tour of the primitives that make a container: namespaces, cgroups, and runc. A container is not a small VM, and this shows you why.

Supported byDigitalOceanDevDojoSMTPfastQuizAPIBecome a sponsor

Container internals · the real path of a docker run

What happens when you run a container

$docker run -p 8080:80 nginx
REST over a Unix socketStep 1 / 8

You run a command

The docker CLI is just a small REST client. It turns your command into an HTTP request and sends it to the Docker daemon over a local socket. The CLI never creates a container itself.

$ curl --unix-socket /var/run/docker.sock http://localhost/v1.45/info

The CLI talks to dockerd exactly like this under the hood.

The whole point: a container is not a small VM. It is one host process that the kernel keeps in its own namespaces and cgroups. Every step above is something you can run yourself on a real Linux box.

About this "how Docker works" simulator

What you'll learn

  • The full path from your terminal down to the Linux kernel
  • The real jobs of the CLI, dockerd, containerd, and runc, and why there are four of them
  • What gets pulled from a registry, and that only missing layers are downloaded
  • How the OCI bundle (config.json + rootfs) describes the container before it exists
  • Which kernel features do the actual isolation: namespaces, cgroups, networking, mounts
  • The real command at each step, so you can reproduce the whole thing yourself

The stack, top to bottom

  • docker CLI: turns your command into an API call over /var/run/docker.sock
  • dockerd: the engine; checks the image, prepares config, pulls if needed
  • containerd: unpacks layers, tracks state, prepares the runtime bundle
  • runc: creates the namespaces and cgroup, then execs your process
  • the kernel: the shared host kernel is the real boundary

A container is not a small VM

The single most important idea in the simulator is the last step. A VM boots a whole guest operating system on virtual hardware. A container does not: nginx is a normal process on your host, and the only thing separating it from everything else is a set of kernel features. Namespaces control what it can see, cgroups control what it can use, and both are just the host kernel doing bookkeeping. That is why a container starts in milliseconds while a VM takes seconds.

Try it on a real host

Every command in the simulator is real. The clean way to poke at namespaces and cgroups without touching your laptop is a throwaway Linux box: spin up a DigitalOcean droplet, run the nginx container, then use lsns, runc list, and cat /sys/fs/cgroup to watch the same pieces the simulator shows. Delete the droplet when you are done.

Go deeper

The companion post, How Docker Really Works, From docker run to the Kernel, walks the same path in depth with the commands to run on a real host, and explains why the split between dockerd, containerd, and runc exists at all.

Try next

Sponsored
Carbon Ads
$ cd /games
// share