The mental model behind every Docker command: images are read-only templates, containers are running instances of them, and volumes, networks and registries handle data, connectivity and distribution.
Docker packages an app with everything it needs (runtime, libraries, config) into an image, then runs it as an isolated process called a container. It shares the host kernel, so it starts in milliseconds and uses far less memory than a virtual machine.
Flow: Dockerfile → docker build → image → docker run → container. Images move between machines through a registry (push / pull).
| Term | What it is | Analogy |
|---|---|---|
| Image | Read-only, layered template (app + dependencies) | A class / an ISO |
| Container | A running (or stopped) instance of an image with its own writable layer | An object / a running VM |
| Dockerfile | Recipe of instructions that builds an image | Source code |
| Layer | One cached filesystem diff per instruction; shared between images | Git commit |
| Registry | Server that stores images (Docker Hub, GHCR, ECR) | npm / Maven Central |
| Tag | Human-readable pointer to an image version (nginx:1.27) | Git tag |
| Volume | Docker-managed storage that outlives containers | External disk |
| Network | Virtual network so containers can reach each other by name | LAN / switch |
| Compose | YAML file describing a multi-container app | Orchestration script |
latest is just a tag name, not "the newest"The docker CLI is a client. It talks over a socket (/var/run/docker.sock) to the Docker daemon (dockerd), which builds images and runs containers through containerd and runc.
Access to docker.sock is effectively root access to the host. Never mount it into untrusted containers.