The Engineering Problems Docker Solves These days almost every software developer has come to know about Docker. In fact, most people use it in their software development journey. Almost everyone knows about Docker—how to write a Dockerfile, how to write a Docker Compose file, how to push or pull images, how to reduce image size, how to configure Docker networks, persistent volumes, Docker commands, etc. But in this blog I am not going to talk about these topics. If you guys have read till here, then let me tell you that I will talk about the problem statements that engineers worked on and solved through Docker. Generally, everyone has heard this: “<b>It works on my machine, but not in production.</b>” Well, this is really a true statement even for running small applications. Due to version incompatibility, production deployments often fail. During production deployment, we must consider a few things such as the OS environment, dependency versions, and we must ensure that the runtime environment is replicated properly. Let me break down this problem into four major parts: <b> Isolation, Resource control, Portability, Storage efficiency </b> Here, isolation means providing a sandbox-like environment, where one process cannot see or interfere with another. <b>Docker solves this problem through Linux namespaces</b>. Namespaces ensure that a container gets its own isolated view of the system, such as its own process ID tree, network interfaces, user IDs, and mount points. The second is resource control. This means preventing a single rogue application from consuming 100% of the host server’s CPU or RAM. The solution is simple:<b> Docker uses Linux control groups (cgroups)</b>. They act as a governor, limiting and isolating resource usage such as CPU, memory, and disk I/O for a collection of processes. The third is portability, which means build once and run anywhere. Code running on a developer’s system should run exactly the same way on staging servers and production servers. This problem is solved using a standardized image format. <b>An image packages the application code, runtime, system tools, system libraries, and settings into one immutable file</b>. The last one is storage efficiency (speed requirement). If every container needs its own OS filesystem, how do we avoid copying gigabytes of data every time a container starts? <b>The solution is to use a Union File System (UnionFS / OverlayFS)</b>. This allows images to be built in layers. If ten containers use the same base Ubuntu image, the system only stores that base image once and shares it across all ten containers, saving massive amounts of disk space and memory. These are some of the problem statements that Docker solves in its own way. Docker is not a perfect technology, but its system architecture can be considered close to perfect. If you have read till now, that’s great. containerd and OCI are also things you should know about. <b>OCI defines the runtime specification and image specification</b>. Let’s also understand some important core components of Docker. <b>Docker Client (CLI)</b>: The interface the user interacts with (e.g., typing docker run). It does not run containers itself; it only sends REST API requests to the Docker daemon. <b>Docker Daemon (dockerd)</b>: The server-side brain. It listens for API requests and manages Docker objects like images, containers, networks, and volumes. <b>containerd</b>: The daemon passes the actual work of managing the container lifecycle (starting, stopping, pausing) to containerd. This separation allows the Docker daemon to be upgraded or restarted without killing all running containers. <b>runc</b>: This is the lowest-level component (the OCI runtime). containerd calls runc to interface with the Linux kernel (setting up namespaces and cgroups) to spawn the container. Once the container is running, runc exits. <b>Docker Registry</b>: A centralized and scalable storage system (like Docker Hub) where users can push and pull immutable image layers. These components together build Docker as a product that millions of people use in production today. Even in Kubernetes, containerd is used as the container runtime. Earlier Kubernetes used Docker directly, but now it has been deprecated.