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 byBecome a sponsor
BitriseAtomsizedDigitalOceanDevDojoSMTPfastQuizAPI

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.

Overview

Typing docker run feels like one action, but it is a hand-off between several programs. This simulator steps through what happens when you run docker run -p 8080:80 nginx, one layer at a time. The CLI sends the request to the Docker daemon, dockerd pulls the image by reading its manifest and downloading the layers, then hands the work to containerd. containerd assembles an OCI runtime bundle, with a config.json that describes the process, its namespaces and its limits, and runc uses that bundle to create the container. The last stages show the running nginx process and the fact that it runs on the host kernel, isolated by namespaces and limited by cgroups rather than by a separate operating system. Each stage also shows the real low-level command you can run on a Linux host to see that layer yourself. The goal is to replace the idea of a container as a small virtual machine with an accurate picture: a normal Linux process that the kernel isolates.

Try this

  1. Press play and let the walkthrough step from the docker run command down to the shared kernel, then step back with the previous button to any layer.
  2. Stop at the runtime bundle stage and read the config.json excerpt to see the process arguments and namespaces handed to runc.
  3. Copy the real command shown at a stage and run it on a Linux host to see the same layer on a live system.

Frequently asked questions

What is the difference between Docker, containerd and runc?
The Docker CLI talks to dockerd, which manages images, networks and volumes. dockerd delegates the container lifecycle to containerd, and containerd uses runc, a low-level OCI runtime, to actually create the isolated process.
Is a container a virtual machine?
No. A container is a regular process on the host that shares the host kernel. Namespaces limit what it can see and cgroups limit what it can use, while a virtual machine runs its own kernel on emulated hardware.
What is an OCI runtime bundle?
A directory with the container root filesystem and a config.json that describes the process to run, its environment, mounts, namespaces and resource limits. OCI runtimes such as runc read it to start the container.

Try next

Sponsored
Carbon Ads
$ cd /games
// share