Why this matters at a senior level
Most Docker issues in production trace back to misunderstandings about container mutability and state persistence. The “hello world” mental model is not enough when you are designing systems that must survive redeploys, rollbacks, and failures. This article frames containers and volumes in the way you need to reason about them in real environments.
Containers: ephemeral runtime over immutable images
A container is a running process instantiated from an image. The image is immutable; the container adds a writable layer on top.
Key implications for architecture:
- You can scale horizontally by creating multiple containers from the same image.
- Runtime changes live only in the container’s writable layer and vanish when the container is removed.
- The filesystem is copy‑on‑write, so writes are not baked into the image.
This is the foundation of immutable infrastructure: all durable change must happen outside the container.
Isolation boundaries and why they matter
Containers use kernel primitives (namespaces and cgroups) to isolate processes. This gives you dependency isolation, resource governance, and predictable runtime behavior.
Practical consequences:
- Multiple versions of the same dependency can coexist across services.
- CPU and memory limits are enforced per workload.
- Debugging is easier because the runtime is defined by the image, not the host.
Isolation is strong but not absolute. Containers share the host kernel, so security posture and privilege boundaries still need to be designed intentionally.
Service‑to‑service communication: isolation with intent
Microservices are useless if they cannot communicate. Docker networking lets you control that explicitly:
- Only containers on the same network can resolve each other by name.
- Lateral communication is constrained to declared networks.
- You can segment workloads by environment or trust boundary.
This is the default posture you want in production: isolate by default, connect deliberately.
The container filesystem is disposable
A container’s writable layer is designed to be thrown away. That is a feature, not a bug.
If you store state in the container filesystem, you will lose it on redeploy, scale‑down, or crash recovery.
This is why stateful services cannot rely on container storage alone.
Volumes: persistent state with lifecycle decoupling
A volume is managed by Docker but stored outside the container’s writable layer. It survives container removal and re‑creation.
This gives you:
- Durability: state is not tied to a specific container instance.
- Portability: the same volume can be attached to replacement containers.
- Operational clarity: the data lifecycle is independent from the compute lifecycle.
In practice, volumes are the standard for databases, queues, and any persistent service.
Failure mode example: Postgres without a volume
- Start a Postgres container.
- Create schema and insert data.
- Remove the container.
Result: all data is gone because it lived in the container’s ephemeral layer.
Now add a volume and mount it to the database data directory. You can replace the container and the state remains intact. That separation of compute vs state is the core operational benefit.
Storage choices: when to use what
- Volumes: production‑grade persistence; managed by Docker.
- Bind mounts: fast local development; host‑filesystem coupling.
- Tmpfs: in‑memory, volatile, useful for sensitive or high‑performance ephemeral data.
In production, volumes should be your default. Bind mounts are generally a local‑dev tool.
Operational best practices
- Treat containers as disposable compute.
- Externalize all state into volumes or managed services.
- Avoid baking secrets into images or layers.
- Document data directories explicitly in service manifests.
- Use health checks to enable safe container replacement.
This is the mindset that makes containerized systems predictable under load and during recovery.
The mental model recruiters expect you to own
- Image: immutable artifact built once.
- Container: short‑lived runtime instance.
- Volume: persistent state that outlives containers.
If you can explain those relationships clearly, you are already ahead of most candidates.
Next steps if you want to go deeper
- Inspect mount points with
docker inspect <container>. - Map Docker networks to Linux bridges and veth pairs.
- Review copy‑on‑write behavior with
overlay2.
This is where Docker stops being a tool and becomes an architectural asset.