Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface. Another Docker client is Docker Compose, that lets you work with applications consisting of a set of containers. Here are the three primary components that make the system work:
It is the command-line interface (CLI) or a desktop application. When you type docker build or docker pull, the client sends these commands to the Docker Daemon using a REST API.
Role: It acts as the primary interface. It doesn't actually run containers; it just sends instructions (API calls) to the Docker Daemon.
Flexibility: A single client can connect to multiple daemons (even remote ones on AWS).
Docker Daemon (dockerd): This is the 'brain' of Docker. It listens for API requests from the client and manages Docker objects like images, containers, networks, and volumes.
containerd & runc: Lower-level runtimes. The daemon delegates the actual 'starting' of a container to containerd, which uses runc (an OCI-compliant tool) to interact with the Linux kernel.
Images: Read-only templates used to create containers. Think of an image as a 'recipe' or a snapshot of a filesystem.
Containers: The runnable instances of images. If an image is a class, a container is an object.
Role: A storage system for images.
Types: Docker Hub (Public) or Amazon ECR (Private).
Workflow: When you run docker pull, the Host checks if the image exists locally; if not, it fetches it from the Registry.
Docker Hub is the default public registry where anyone can find or share images.
When you execute a docker pull command, the host fetches the requested image from the registry and stores it locally.