Key Points about Docker

Docker packages an application together with its runtime, libraries and configuration into an image, and runs that image as an isolated process called a container. Containers share the host's Linux kernel, so they start in well under a second and use far less memory than virtual machines, while still giving each application its own filesystem, network stack and process tree. This page summarises the key ideas, then explains the architecture behind docker run, how images are built from layers, a complete worked example, and the trade-offs and mistakes that matter in practice.

1. Key points

2. Architecture

What happens on docker run docker CLI client dockerd REST API over unix socket containerd image + container lifecycle Registry Docker Hub, ECR, GHCR runc creates namespaces + cgroups Container process isolated, shares host kernel

The docker command is only a client. It sends API calls to the Docker daemon, dockerd, usually over /var/run/docker.sock. The daemon pulls the image from a registry if it is not cached, then hands the work to containerd, which manages images and container lifecycles, and containerd calls an OCI runtime, normally runc, to create the process. Isolation comes from Linux kernel features rather than from a hypervisor: namespaces give the process its own view of process IDs, mounts, network interfaces, hostname and users, and cgroups limit CPU, memory and I/O. On macOS and Windows, Docker Desktop runs a small Linux VM to supply that kernel.

3. Images and layers

An image is a stack of read-only layers Container layer writable, discarded with container COPY app/ . your code, changes often RUN pip install -r requirements.txt dependencies FROM python:3.12-slim base image layers top of stack bottom of stack

Each Dockerfile instruction that changes the filesystem produces a layer, identified by a content hash. Layers are shared between images and cached between builds; when you rebuild, Docker reuses every layer up to the first instruction whose inputs changed. A running container adds a thin writable layer on top using a union filesystem (overlay2 on most Linux hosts). Anything written there disappears when the container is removed, which is why persistent data belongs in volumes.

Order instructions from least to most frequently changing. Copying requirements.txt and installing dependencies before copying the source code means an ordinary code edit rebuilds only the last layer.

4. Worked example: containerising a Python web app

# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd --create-home appuser
USER appuser
EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]
docker build -t myapp:1.0 .
docker run -d --name myapp -p 8000:8000 \
    -e DATABASE_URL=postgresql://db/app \
    -v myapp-data:/app/data \
    --memory 512m --cpus 1 myapp:1.0

docker ps                       # running containers
docker logs -f myapp            # stream stdout/stderr
docker exec -it myapp sh        # shell inside the container
docker stop myapp && docker rm myapp
docker image prune              # remove dangling images

For several cooperating containers, describe them in a compose.yaml file and start them with docker compose up -d; Compose creates a private network where services reach each other by name.

5. Containers versus alternatives

OptionIsolationStart timeUse when
Docker containerKernel namespaces and cgroupsSub-secondPackaging and running services consistently across machines
Virtual machineHypervisor, separate kernelSeconds to minutesUntrusted workloads, different OS kernels
PodmanSame as Docker, daemonless, rootless by defaultSub-secondNo root daemon allowed; Docker-compatible CLI
KubernetesContainers plus schedulingSecondsRunning many containers across a cluster with self-healing and scaling

6. Pitfalls