Docker Architecture: Engine, Daemon, Client and Registries

Beginner
10 min

Docker Architecture: Engine, Daemon, Client and Registries

Docker is not one program but a small stack of cooperating pieces: a command-line client, a long-running daemon, a container runtime, and registries that store images. In this lesson you will learn how those pieces fit together, which Linux features make containers possible, and how to read docker version and docker info with confidence.

The Client-Server Model

Docker uses a client-server architecture. The docker command you type is only a thin client. It sends requests over a REST API to the Docker daemon (dockerd), which builds images, starts containers, manages networks and volumes, and talks to registries.

On Linux the client and daemon communicate through the Unix socket /var/run/docker.sock. On Windows a named pipe is used, and with Docker Desktop on macOS or Windows the daemon runs inside a lightweight Linux virtual machine that Desktop manages for you.

bash
docker version
text
Client: Version: 28.3.2 API version: 1.51 Server: Docker Engine - Community Engine: 28.3.2 containerd: 1.7.27 runc: 1.2.5

Two consequences follow from this design:

  • The client can talk to any daemon, local or remote. Set DOCKER_HOST or create a context with docker context create, and the same commands manage containers on a server over SSH.
  • Whoever can reach the socket has root-equivalent control over the host. Access to docker.sock is a security boundary, a point we revisit in the security lessons.

Inside the Engine: dockerd, containerd and runc

The daemon delegates low-level work to smaller components that follow the open standards of the Open Container Initiative (OCI):

| Component | Role | |-----------|------| | dockerd | Exposes the API, builds images, manages networks, volumes, logs and the image store | | containerd | Supervises container lifecycles, pulls images, manages snapshots | | runc | The OCI runtime that creates the container process from a bundle, then exits | | BuildKit | The builder backend behind docker build; handles caching and parallel stages |

Because these layers speak OCI formats, an image built by Docker runs unchanged under Kubernetes, Podman, or any other OCI-compliant tool.

What a Container Really Is

A container is not a virtual machine. It is an ordinary Linux process (or group of processes) that the kernel isolates and limits using three features:

  • Namespaces give the process its own view of the system: process IDs (pid), network stack (net), mount table (mnt), hostname (uts), inter-process communication (ipc) and optionally user IDs (user).
  • Control groups (cgroups) cap how much CPU, memory and I/O the process may consume.
  • Union filesystems such as overlay2 stack read-only image layers and add a thin writable layer on top, so many containers share one copy of an image on disk.

You can see this from the host. Start a container and look at its processes:

bash
docker run -d --name web nginx:alpine docker top web
text
UID PID PPID CMD root 21345 21324 nginx: master process nginx -g daemon off; 101 21390 21345 nginx: worker process

Those PIDs are real host processes. Inside the container the master process believes it is PID 1, which is why signal handling for PID 1 matters, a topic covered in the CMD vs ENTRYPOINT lesson.

Images, Layers and Registries

An image is a read-only template made of stacked layers plus a JSON manifest that lists them. A registry stores and serves images; Docker Hub is the default, but GitHub Container Registry, cloud provider registries and self-hosted registries all speak the same OCI distribution API.

The flow for docker run nginx:alpine on a fresh machine is:

  1. The client asks the daemon to create a container from nginx:alpine.
  2. The daemon finds the image missing from its local store.
  3. containerd pulls the manifest and each missing layer from docker.io/library/nginx.
  4. The layers are unpacked into the overlay2 storage directory.
  5. runc creates the isolated process with a writable layer on top.

Run the same command again and steps 2 through 4 are skipped because the layers are already cached. Everything lives under the Docker root directory (/var/lib/docker on Linux); docker info --format '{{.DockerRootDir}}' prints its location, and it is the first place to look when disk space runs out.

Common Mistakes

  • Trying to ssh into a container as if it were a VM. Use docker exec; containers do not run an SSH server.
  • Forgetting which daemon you are connected to. Check docker context ls when docker ps shows unfamiliar containers.
  • Mounting docker.sock into untrusted containers. Anyone with socket access can start a privileged container and read the host filesystem.
Quick Quiz
Question 1 of 3

Which component actually creates the isolated container process from an OCI bundle?

Key Takeaways

  • The docker CLI is a client; the daemon (dockerd) does the real work and can be local or remote.
  • dockerd delegates to containerd and runc, which implement the open OCI standards.
  • A container is a normal process isolated by namespaces, limited by cgroups and backed by a layered filesystem.
  • Images are stacks of read-only layers pulled from registries and cached in the Docker root directory.
  • Access to the Docker socket is equivalent to root access on the host.

Next lesson: Installing Docker and First Commands — install Docker on your machine and run your first containers.

Docker Architecture: Engine, Daemon, Client and Registries - Docker | CodeYourCraft | CodeYourCraft