Skip to content

Docker — How It Works

Core mechanisms, container lifecycle, image layer system, and networking internals.

Container Lifecycle

stateDiagram-v2
    [*] --> Created: docker create
    Created --> Running: docker start
    Running --> Paused: docker pause
    Paused --> Running: docker unpause
    Running --> Stopped: docker stop (SIGTERM → SIGKILL)
    Stopped --> Running: docker start
    Stopped --> Removed: docker rm
    Running --> Removed: docker rm -f
    Removed --> [*]
    Running --> Restarting: crash / restart policy
    Restarting --> Running: restart

Image Layer System

Docker images use a Union File System (overlay2 by default) that stacks read-only layers. Each Dockerfile instruction creates a new layer. When a container runs, a thin writable layer is added on top.

flowchart TB
    subgraph Image["Image Layers (read-only)"]
        L1["Layer 1: Base OS\n(ubuntu:24.04)"]
        L2["Layer 2: apt-get install\n(python, pip)"]
        L3["Layer 3: COPY app/\n(application code)"]
        L4["Layer 4: RUN pip install\n(dependencies)"]
    end

    subgraph Container["Container Layer (read-write)"]
        RW["Writable Layer\n(runtime state, logs, temp files)"]
    end

    RW --> L4 --> L3 --> L2 --> L1

    style Container fill:#0db7ed,color:#fff
    style Image fill:#1565c0,color:#fff

Copy-on-Write (CoW)

  • When a container modifies a file from a lower layer, it is copied up to the writable layer
  • Original layers remain unchanged → multiple containers share the same base layers
  • Deleting a file in the container creates a whiteout entry, hiding the lower layer file

BuildKit Pipeline

sequenceDiagram
    participant User as Developer
    participant CLI as docker CLI
    participant BK as BuildKit
    participant Registry as Registry

    User->>CLI: docker build .
    CLI->>BK: Send Dockerfile + context
    BK->>BK: Parse Dockerfile → DAG
    BK->>BK: Resolve cache (local/registry)
    par Parallel Layer Builds
        BK->>BK: Stage 1 (base image)
        BK->>BK: Stage 2 (dependencies)
        BK->>BK: Stage 3 (application)
    end
    BK->>BK: Merge stages → final image
    BK->>Registry: Push (if --push)
    BK->>CLI: Return image ID
    CLI->>User: Successfully built

Key BuildKit Features

Feature Detail
Parallel builds Independent stages execute concurrently
Cache mounts --mount=type=cache for package manager caches
Secret mounts --mount=type=secret — never persisted in layers
Multi-platform Build for arm64, amd64, etc. in single command
Registry cache --cache-to type=registry for CI pipelines

Networking Model

flowchart LR
    subgraph Host["Docker Host"]
        subgraph Bridge["docker0 bridge (172.17.0.0/16)"]
            C1["Container 1\n172.17.0.2"]
            C2["Container 2\n172.17.0.3"]
        end
        subgraph UserNet["user-network (10.0.0.0/24)"]
            C3["Container 3\n10.0.0.2"]
            C4["Container 4\n10.0.0.3"]
        end
        IPTABLES["iptables / nftables\n(NAT, port mapping)"]
    end

    Internet["Internet"] <-->|"port mapping\n-p 8080:80"| IPTABLES
    IPTABLES <--> Bridge
    IPTABLES <--> UserNet

    style Bridge fill:#0db7ed,color:#fff
    style UserNet fill:#2e7d32,color:#fff

Network Drivers

Driver Use Case
bridge Default single-host networking; containers on same host communicate via veth pairs
host Container shares host network namespace; no isolation, maximum performance
overlay Multi-host networking via VXLAN; used by Swarm/K8s
macvlan Container gets own MAC address; appears as physical device on network
ipvlan Like macvlan but shares host MAC; L2 or L3 mode
none No networking; container is completely isolated

Storage Model

Storage Type Lifecycle Use Case
Union FS layers Tied to container Ephemeral container filesystem
Named volumes Independent of container Databases, persistent state
Bind mounts Host path → container Development (live code reload)
tmpfs In-memory only Temporary sensitive data
Volume plugins Driver-dependent NFS, EBS, Ceph, etc.

Sources