Skip to main content
In this walkthrough we’ll follow the exact sequence of events that occur when you run docker run against the official NGINX image. This is a practical, interview-ready explanation that ties Docker components to the underlying Linux kernel features—namespaces, cgroups, union filesystems, and the container runtimes. Read the steps below to understand how a simple docker run nginx becomes an isolated, networked process on your host.
  1. Docker client → Docker daemon
  1. Check for the image locally (pull if needed)
  • Dockerd looks in the local image store for the requested image tag (for example, nginx:latest).
  • If the image is missing, dockerd pulls it from a registry such as Docker Hub and stores the image layers on the host so future runs can reuse them.
  • Registry: https://hub.docker.com/
  1. Image layers and the writable container layer
  • A Docker image is built from multiple read-only layers stacked together (base OS, runtime binaries, app files, etc.).
  • When creating a container, Docker mounts a thin writable layer on top of those read-only layers (typically using a union filesystem like overlay2).
  • Runtime changes—logs, temporary files, and other state—are written into that writable layer unique to the container, enabling multiple containers to share the same underlying image layers efficiently.
  • Storage driver docs: https://docs.docker.com/storage/storagedriver/overlayfs-driver/
The image illustrates the process of pulling a Docker image of Nginx from Docker Hub to a local machine and running it in an isolated container with its own filesystem and network.
  1. Container = a normal Linux process in an isolated environment
  • Under the hood, a container is one or more standard Linux processes started by the runtime. Inside the container, the main process runs as PID 1 within a separate PID namespace.
  • The OCI runtime (runc or equivalent) sets up namespaces, mounts, and cgroups, and then execs the container process (NGINX in this case).
  • The container process is still a host process, but kernel primitives make it appear isolated.
A container is simply regular Linux processes with kernel-enforced isolation. From the process’s perspective it has its own filesystem, network interfaces, and process table—even though the kernel is shared with the host.
  1. Isolation via namespaces (what a container can see)
  • Linux namespaces isolate what a process can observe and interact with:
    • PID namespace — container processes see only the container’s PID tree.
    • Mount namespace — gives the container a private view of the filesystem (image layers + writable layer).
    • Network namespace — provides a separate networking stack (interfaces, routing, IPs).
    • UTS, IPC, and user namespaces — isolate hostname, interprocess communication, and user/group IDs.
  • Namespaces act like separate rooms inside the same building: each room (namespace) has its own view while sharing the same kernel.
Namespaces quick reference:
The image illustrates a concept of containerization, showing how an image is composed of multiple layers, with writable and read-only layers used by multiple containers.
  1. Resource control via cgroups (what a container can use)
  • Control groups (cgroups v2) limit and account for resource usage: CPU shares, memory limits, block I/O, and more.
  • When you pass runtime limits like --memory or --cpus to docker run, Docker creates a cgroup for that container and writes the limits; the kernel enforces them. Exceeding memory limits can trigger the OOM killer.
  • Example:
  1. Networking: how a container talks to the outside world
  • By default, Docker connects containers to a host-level bridge network. Each container receives its own network namespace, an interface (e.g., eth0), and an internal IP on the bridge.
  • Containers can initiate outbound connections directly. To expose container services to external clients, you publish a host port and map it to the container port. Docker sets up DNAT rules (via iptables/netfilter) or uses its networking proxy to forward traffic.
  • Example (publish port 80 in the container on host port 8080):
The image illustrates namespaces as walls in a building, representing containerization, with different containers sharing a Linux kernel on a host machine. Two stick figures labeled "Interviewer" and "Candidate" are present, emphasizing a discussion or explanation context.
  1. Final startup steps
  • Dockerd ensures mounts, namespaces, and cgroups are configured, then the runtime execs NGINX as the container’s PID 1.
  • Container logs and runtime state go to the container’s writable layer unless you bind-mount directories or use Docker volumes for persistence or sharing.
  • Use bind mounts or volumes to persist configuration, logs, or state across container restarts, for example:
Summary — concise flow
  • docker CLI → dockerd → check/pull image → assemble filesystem (read-only image layers + writable layer) → set up namespaces (PID, network, mount, etc.) → configure cgroups → configure networking and port mappings → start the container process (NGINX) as PID 1.
  • This mix of image layering, namespaces, and cgroups is what makes containers lightweight, isolated, and resource-controlled.
Quick command examples Further reading and references

Watch Video