How Docker Works Under the Hood
You already know that Docker packages apps into containers. Now it is time to understand what actually happens inside your computer when Docker runs. You do not need to be a Linux expert — this topic uses plain language and visual diagrams to explain the mechanics.
Your Computer's Operating System Has Layers
Think of your computer like a building. The ground floor is the hardware — the CPU, memory, and storage. The next floor up is the operating system kernel — the core of Linux or Windows that talks directly to the hardware. Above that sit all your applications — your browser, your code editor, your games.
Docker works at the kernel level. It uses features already built into Linux to create isolated spaces called containers. These isolated spaces behave like separate computers, but they all share the same kernel on the ground floor.
Two Linux Features That Make Docker Possible
Docker relies on two powerful Linux technologies: namespaces and cgroups.
Namespaces — The Walls Between Containers
A namespace gives each container its own private view of the system. Think of namespaces as the walls inside an office building. Every office looks complete — it has its own entrance, its own desk, its own network of computers. But all offices share the same building structure.
Docker uses six namespaces:
- PID namespace: Each container sees only its own processes. Container A cannot see the processes running inside Container B.
- Network namespace: Each container gets its own network interface and IP address.
- Mount namespace: Each container has its own file system view. Files inside Container A are invisible to Container B.
- UTS namespace: Each container can have its own hostname.
- IPC namespace: Containers cannot accidentally share memory with each other.
- User namespace: A container can run as root inside itself but not on the host system.
cgroups — The Resource Budget for Each Container
Control Groups (cgroups) limit how much CPU, memory, and disk bandwidth each container can use. Without cgroups, one container could hog all the CPU and starve the others. With cgroups, you tell Docker: "This container gets a maximum of 1 CPU core and 512 MB of memory." The kernel enforces that budget.
How a Container Starts — Step by Step
You type: docker run nginx
Step 1: Docker checks your local image library
└── Image found? Use it. Image missing? Download from Docker Hub.
Step 2: Docker Engine creates a new process on your host OS
└── Applies namespaces → container gets isolated PID, network, filesystem
Step 3: Docker sets up a writable filesystem layer on top of the image
└── Image layers (read-only) + new container layer (writable)
Step 4: Docker connects the container to a virtual network
└── Assigns a private IP address (e.g., 172.17.0.2)
Step 5: Docker starts the process inside the container
└── nginx starts, listens on port 80 inside the container
Container is now running. Isolated. Lightweight.
The Union File System — How Layers Work
Docker images are made of layers stacked on top of each other like pancakes. Each layer represents a change — adding a file, installing a library, changing a setting. When you run a container, Docker adds one more thin, writable layer on top. The container writes its changes to this top layer only.
Docker Image Layers (read-only): ┌─────────────────────────────┐ │ Layer 4: Your app code │ ← added by your Dockerfile ├─────────────────────────────┤ │ Layer 3: Python libraries │ ← pip install ran here ├─────────────────────────────┤ │ Layer 2: Python 3.10 │ ← python installed here ├─────────────────────────────┤ │ Layer 1: Ubuntu 22.04 base │ ← starting point └─────────────────────────────┘ When container runs, one writable layer is added on top: ┌─────────────────────────────┐ │ Container layer (writable) │ ← logs, temp files go here ├─────────────────────────────┤ │ ... all image layers below │ ← unchanged, read-only └─────────────────────────────┘
This design means ten containers running from the same image all share the same read-only layers on disk. Only the thin writable top layer is unique per container. This saves a huge amount of storage space.
The Docker Engine — The Central Manager
The Docker Engine is the software running in the background on your machine. It has three parts:
Docker Daemon (dockerd): The background service that does all the work — building images, starting containers, managing networks. It runs continuously after you install Docker.
REST API: An interface that lets programs talk to the Docker daemon programmatically.
Docker CLI: The command-line tool you use directly. When you type docker run, the CLI sends a request to the daemon, which does the actual work.
You type a command
↓
Docker CLI (client)
↓ sends API request
Docker Daemon (server) ← manages everything
↓
Linux Kernel (namespaces + cgroups)
↓
Container runs
Windows and macOS — What Changes
Docker containers need a Linux kernel. On Linux, Docker runs directly on your OS kernel. On Windows and macOS, Docker automatically creates a small, lightweight Linux virtual machine in the background. Your containers run inside that VM. You never see it — Docker handles it transparently.
