Docker packages an application plus its dependencies into a portable unit you can run the same way on a laptop, in CI, and in production. If you are trying to understand how Docker works—not just which commands to copy—this guide walks through images, layers, the container runtime, and what happens from docker build to a running process.
The problem Docker solves
Before containers, “it works on my machine” usually meant mismatched library versions, OS packages, or environment variables. Virtual machines solved isolation but paid a heavy cost in boot time and disk. Docker sits in the middle: OS-level isolation via Linux namespaces and cgroups, sharing the host kernel while giving each container its own filesystem view, process tree, and resource limits.
You get reproducible builds, fast startup, and a standard artifact (the image) that flows through registry → orchestrator → host.
Images vs containers
An image is a read-only template: filesystem snapshots stacked in layers plus metadata (default command, env vars, exposed ports). A container is a runnable instance of an image—think of it as a thin writable layer on top with a live process.
When you docker run nginx, Docker:
- Pulls the image if missing (layer downloads are cached).
- Creates a container with a unique ID.
- Applies storage, network, and cgroup configuration.
- Starts the process defined in the image (often PID 1 is
nginx).
Stopping a container pauses processes; removing it deletes the writable layer unless you commit it to a new image.
Layers and the build cache
Docker images are built from a Dockerfile as a series of instructions (FROM, RUN, COPY, etc.). Each instruction creates a layer. Layers are content-addressed and reused across images, which is why builds get faster after the first time.
Example mental model:
Layer 4: COPY app /app
Layer 3: RUN npm ci
Layer 2: COPY package*.json ./
Layer 1: FROM node:20-bookworm-slim
Order matters for cache hits. Put slow-changing steps early and frequently edited source copies late. Multi-stage builds let you compile in a fat builder image and copy only binaries into a slim runtime image—smaller attack surface and faster deploys.
What docker build actually does
The Docker CLI sends your Dockerfile and build context to the builder (classic builder or BuildKit). BuildKit can parallelize steps and improve caching. The output is an image tagged locally (myapi:1.2.0). Nothing runs yet—no container exists until docker run or your orchestrator schedules it.
Security note: the build context includes everything sent to the daemon unless .dockerignore trims it. Never COPY secrets; inject them at runtime with orchestrator secrets or environment management.
The container runtime stack
On a typical Linux host:
- containerd (or similar) manages image pull, snapshot mounts, and container lifecycle.
- runc is the low-level tool that creates namespaces and starts the user process.
- Docker Engine (or another CRI-compatible runtime in Kubernetes) orchestrates these pieces for you.
On macOS and Windows, Docker Desktop runs a Linux VM; containers execute inside that VM even though your CLI feels local.
Namespaces and cgroups (why isolation works)
Namespaces partition kernel resources:
- PID — process tree isolation
- NET — network interfaces and routing
- MNT — filesystem mount points
- UTS — hostname
- IPC — inter-process communication
cgroups limit and account for CPU, memory, and I/O. Without cgroup limits, one container can starve others on the same host. In Kubernetes, requests and limits map to cgroup settings under the hood.
Networking in plain terms
Default bridge networking gives each container a virtual interface and private IP on a bridge. Published ports (-p 8080:80) set up NAT rules so host traffic reaches the container.
In Compose or Kubernetes, you usually rely on service DNS names instead of hard-coded IPs. Containers on the same user-defined network can resolve each other by name.
Storage: volumes and bind mounts
Container filesystems are ephemeral. For databases and uploads, attach:
- Volumes — managed by Docker, portable across hosts (with plugins in enterprise setups).
- Bind mounts — map a host path for fast local dev.
Images remain immutable; persistent data should never live only in the container layer you delete on docker rm.
How orchestrators use the same primitives
Kubernetes does not replace Docker’s core ideas—it schedules pods that run container images, sets resource limits, mounts volumes, and configures networking via CNI plugins. The artifact is still an image pulled from a registry.
Understanding Docker layers and runtime behavior makes Kubernetes debugging easier: when a pod crashes, you are still looking at image entrypoints, missing env vars, and cgroup OOM kills.
Practical workflow tips
Pin base image digests in production Dockerfiles (FROM node@sha256:...) to avoid surprise upstream changes.
Run as non-root inside the image. Create a user in the Dockerfile and set USER.
Use .dockerignore aggressively to keep contexts small and avoid leaking files.
Health checks belong in orchestrators, but local HEALTHCHECK instructions help during bare Docker runs.
One process per container is a guideline, not a law—but if you bundle nginx + app + cron, be explicit about supervision and signals.
Troubleshooting mental checklist
| Symptom | Likely cause |
|---|---|
exec format error | Wrong architecture image (arm vs amd64) |
| Immediate exit code 0 | Missing long-running CMD; container finished |
| Cannot connect to service | Wrong port publish or app binding to 127.0.0.1 instead of 0.0.0.0 |
| OOMKilled | Memory limit too low for JVM/Node heap |
| Slow builds | Poor layer ordering; huge context |
docker logs shows stdout/stderr from PID 1. If your app logs to files inside the container without forwarding, logs disappear with the container.
FAQ
Are Docker containers virtual machines?
No. They share the host kernel and isolate processes with namespaces. VMs emulate hardware and run separate kernels.
Is Docker only for Linux?
Linux containers are native. Other platforms run Linux VMs to host them.
How is Docker different from Kubernetes?
Docker (or containerd) runs containers on one machine. Kubernetes schedules many containers across a cluster, handles rollouts, secrets, and service discovery.
Do I still need configuration management tools?
Often yes for the host OS and cluster, but application configuration increasingly lives in images plus environment-specific injectors.
Compose and multi-container apps
Docker Compose describes several services in one YAML file: web, database, cache. docker compose up creates a project network, starts dependencies in order (with health checks if configured), and mounts development volumes. Compose is ideal for local parity with production topology without running a full Kubernetes cluster on your laptop.
For production, many teams build the same images in CI, push to ECR/GHCR/Artifact Registry, and deploy with ECS, EKS, or Fly.io—but the image artifact is identical to what you tested locally.
Security scanning and supply chain
Images bundle OS packages and language dependencies. Scan images in CI with tools that understand CVE databases (Trivy, Grype, Docker Scout). Pin versions, rebuild regularly, and treat critical CVEs in base images as incidents—even if your application code never changed.
Sign images with cosign or Notary v2 where your platform supports verification at deploy time.
Signals and graceful shutdown
Containers receive POSIX signals. PID 1 should handle SIGTERM to drain connections before exit. Node apps often need explicit signal handlers; Java apps may require -XX:+UseContainerSupport so the JVM respects cgroup memory limits.
Orchestrators send SIGTERM before SIGKILL; if your app ignores termination, you will see stuck deploys and corrupted half-written data.
Docker’s commands are the surface; namespaces, layered images, and a small set of runtime daemons are the substance. Once that model clicks, reading Compose files, CI pipelines, and Kubernetes manifests becomes much less mysterious—you are tracing the same image from build to running process, with networking and storage attached at the last mile.
Further Reading
Discover more articles on similar topics across our network
How Schools and Hospitals Support People Working to Rebuild Communication
Venture
Comments
Loading comments…