Docker Lesson 4 – Docker Architecture | Dataplexa
Section I · Lesson 4

Docker Architecture

Every time you type a Docker command, three separate pieces of software spring into action. Understanding who does what — and how they talk to each other — makes every error message, every timeout, and every successful build make complete sense.

Most beginners treat Docker like a black box — you type a command, something happens. This lesson opens the box. By the end, you'll have a clear mental model of the entire system, and that model will serve you all the way through to production deployments.

The Three Core Components

Docker's architecture is built around three distinct pieces: the Docker Client, the Docker Daemon, and the Docker Registry. Each has a single, well-defined job. None of them does the other's job. Together, they handle everything from typing a command to a container running in production.

The Restaurant Analogy

Think of a restaurant. You — the customer — place an order with the waiter. The waiter doesn't cook anything. They carry your request to the kitchen, where the chef does all the actual work. The ingredients come from a supplier who delivers them as needed. The Docker Client is the waiter. The Docker Daemon is the kitchen. The Registry is the supplier.

The Docker Client

The Docker Client is the tool you interact with every day — the docker command in your terminal. Every time you type docker run, docker build, or docker ps, you're talking to the Docker Client.

Here's the important thing: the Client does absolutely nothing by itself. It's a pure messenger. It takes your command, translates it into an API call, sends it to the Docker Daemon over a REST API, and waits for a response. That's it. All the real work happens somewhere else.

The Client and the Daemon don't have to be on the same machine. A DevOps engineer can run the Docker Client on their laptop and have it talk to a Docker Daemon running on a remote server in AWS. The communication happens over a network socket — locally via a Unix socket, or remotely over TCP.

The Docker Daemon

The Docker Daemon — also called dockerd — is the engine running silently in the background on your machine. It's the component that actually builds images, creates containers, manages networks, and handles storage volumes. Every piece of real work in Docker is done by the Daemon.

The Daemon listens for API requests from the Client. When you run docker build, the Client sends a build request to the Daemon. The Daemon reads your Dockerfile, executes each instruction, and produces an image. When you run docker run, the Daemon creates a container from the image, sets up the networking, mounts volumes, and starts the process.

The Daemon also manages the local image cache. Every image you pull gets stored locally by the Daemon. The next time you need that image, the Daemon serves it from cache instead of downloading it again. This is why your second docker run is always faster than the first.

The Docker Registry

The Registry is where Docker images live when they're not on your machine. Think of it as GitHub — but instead of storing code repositories, it stores Docker images. The default public registry is Docker Hub, and it hosts hundreds of thousands of images — official ones for nginx, PostgreSQL, Node.js, Python, Redis, and virtually every popular piece of software.

The Daemon talks to the Registry in two directions. A docker pull downloads an image from the Registry to the local cache. A docker push uploads a locally built image up to the Registry so others can use it. Your CI/CD pipeline builds an image, pushes it to the Registry, and your production server pulls it down and runs it — that's the complete delivery cycle.

Registries can be public or private. Docker Hub is the public default. Companies running sensitive workloads run their own private registries — either self-hosted or using a managed service like AWS ECR, Google Artifact Registry, or GitHub Container Registry.

Docker Architecture — The Full Picture

Docker Client
docker CLI
REST API

Docker Daemon (dockerd)

Images
Containers
Networks
Volumes
push / pull
Registry
Docker Hub / ECR

You type a command → the Client sends it to the Daemon via REST API → the Daemon does the work → if it needs an image, it talks to the Registry.

The Flow of a Single docker run Command

A lot happens between pressing Enter and a container running. Tracing through it once makes everything click.

Life of a docker run command

Step 1 — You type the command

You run docker run nginx in your terminal. The Docker Client receives this instruction.

Step 2 — Client calls the Daemon

The Client translates your command into a REST API call and sends it to the Docker Daemon running on your machine.

Step 3 — Daemon checks local cache

The Daemon looks for the nginx image in its local cache. If it's there, it skips to Step 5. If not, it moves to Step 4.

Step 4 — Daemon pulls from Registry

The Daemon contacts Docker Hub, authenticates if needed, and downloads the nginx image layer by layer. Each layer is cached locally for next time.

Step 5 — Daemon creates and starts the container

The Daemon creates a container from the image, sets up isolated networking and filesystem, and starts the process. Your container is running.

Seeing It in Action

The scenario: You're a full-stack developer setting up a local development environment. You need a PostgreSQL database running locally — no installation, no system configuration, just a container. You also want to see the architecture in action — the Client calling the Daemon, the Daemon pulling from Docker Hub.

docker pull postgres:15-alpine
# docker      → the Docker Client — your messenger
# pull        → instruction to fetch an image from the Registry
# postgres    → the image name on Docker Hub
# :15-alpine  → the specific tag — version 15, Alpine Linux base (lightweight)
15-alpine: Pulling from library/postgres
96526aa774ef: Pull complete
6f78c4f8d608: Pull complete
a0c3cf4a4a73: Pull complete
d9f4d3c65212: Pull complete
3a4b9e4cf9a7: Pull complete
Digest: sha256:3d7c6d5d4b2e1f8a9c0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0
Status: Downloaded newer image for postgres:15-alpine
docker.io/library/postgres:15-alpine

What just happened?

Each line starting with a hash and letters — 96526aa774ef: Pull complete — is one image layer being downloaded. Docker images aren't monolithic files. They're stacks of layers, and the Daemon downloads each layer separately. That's why the progress shows multiple lines. It's also why Docker is so efficient — if two images share a layer (like the same Alpine Linux base), the Daemon only stores that layer once and shares it between both images. The final line confirms the full image reference: docker.io/library/postgres:15-alpine. That's the Registry (docker.io), the namespace (library — meaning official images), the name, and the tag.

docker run -d \
  --name db-container \
  -e POSTGRES_PASSWORD=secret123 \
  -p 5432:5432 \
  postgres:15-alpine
# -d                          → detached: run in background, return control to terminal
# --name db-container         → give it a readable name instead of a random one
# -e POSTGRES_PASSWORD=...    → pass an environment variable into the container
# -p 5432:5432                → map host port 5432 to container port 5432
# postgres:15-alpine          → the image to create the container from
b7e1a4c52f88d3a9e0c1f2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2

What just happened?

The Docker Client received this command, packaged it as an API call, and sent it to the Daemon. The Daemon found postgres:15-alpine in its local cache (from the pull we just did), created a new container from it, set up the isolated network namespace, configured the port mapping so your local port 5432 reaches the container's port 5432, injected the environment variable as a configuration parameter, and started the PostgreSQL process inside the container. That single container ID printed back is the Daemon's confirmation that all of that worked. Your database is live and reachable at localhost:5432.

Teacher's Note

If Docker ever throws a "Cannot connect to the Docker daemon" error, it means the Daemon isn't running — not that your command is wrong. On macOS and Windows, open Docker Desktop. On Linux, run sudo systemctl start docker.

Practice Questions

1. The Docker component that actually builds images, creates containers, and manages networks is called the Docker what?



2. The Docker Client communicates with the Docker Daemon using which type of API?



3. The default public registry Docker uses to pull and push images is called what?



Quiz

1. When you type docker run in your terminal, what does the Docker Client do?


2. When the Docker Daemon receives a run request for an image, what happens first?


3. You run a Docker command and get the error "Cannot connect to the Docker daemon." What does this mean?


Up Next · Lesson 5

Installing Docker

You know the architecture — now let's get Docker running on your machine and verify every piece of it is working correctly.