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