Docker Complete Guide: Containers, Images, Multi-Stage Builds & Security
Docker is the foundation of modern DevOps. Every CI/CD pipeline builds Docker images. Every Kubernetes workload runs Docker containers. Docker images are built and shipped daily in real enterprise environments — managing multi-stage Dockerfiles, enforcing security hardening policies, and debugging container networking issues in production. This guide is everything I wish I had known when I started.
What is Docker? The Core Concept
Docker packages an application and all its dependencies into a portable, self-contained unit called a container. Containers solve the "works on my machine" problem permanently — the same container image runs identically on a developer's MacBook, a CI runner, a staging server, and a production Kubernetes cluster.
Under the hood, Docker uses two Linux kernel features: namespaces (for process, network, and filesystem isolation between containers) and cgroups (to limit CPU and memory usage). Docker itself is not magic — it is a user-friendly wrapper around these kernel primitives. Understanding this is important for security discussions in interviews.
Docker Image Layers — How They Work
A Docker image is built from a stack of read-only layers. Each instruction in a Dockerfile (FROM, RUN, COPY, etc.) creates a new layer. When you run a container, Docker adds a thin writable layer on top. All containers from the same image share the read-only layers — this is how Docker achieves storage efficiency.
Layer caching is what makes Docker builds fast. If a layer's instruction and its inputs have not changed, Docker reuses the cached layer. This has a critical implication for Dockerfile ordering: put instructions that change rarely (installing OS packages) early, and instructions that change frequently (copying your application code) late.
Multi-Stage Builds — Production Best Practice
Multi-stage builds are the most important Dockerfile pattern for production. They allow you to use a large build-time image (with compilers, build tools, test frameworks) while producing a tiny runtime image (just the application binary and its runtime dependencies). The final image contains none of the build tools — reducing attack surface and image size dramatically.
["java", "-jar", "app.jar"])
not shell form (java -jar app.jar). Shell form wraps your process in /bin/sh -c,
making your app a child of the shell. When Kubernetes sends SIGTERM for graceful shutdown, the shell
intercepts it — your app never gets the signal and waits for the full terminationGracePeriodSeconds.
This is a very common source of slow Kubernetes rolling updates.
Docker Networking Modes
- bridge (default) — Each container gets its own network namespace on a private bridge network. Containers communicate by container name. Port mapping (
-p 8080:80) exposes container ports to the host. - host — Container shares the host's network stack. No network isolation. Use only when you need maximum network performance (e.g., monitoring agents). Never for application containers.
- none — No networking. Completely isolated. Use for batch jobs that process local files with no network requirement.
- overlay — Multi-host networking for Docker Swarm. Containers on different hosts can communicate. Kubernetes uses its own networking model and does not use Docker overlay networks.
Docker Volumes — Managing Persistent Data
Containers are ephemeral — all data written inside a container is lost when the container is removed. Volumes solve this. There are three types:
- Named volumes (
docker run -v pgdata:/var/lib/postgresql/data postgres) — Managed by Docker, stored in Docker's storage area. Preferred for production data. Persists across container restarts and removals. - Bind mounts (
docker run -v /host/path:/container/path myapp) — Maps a specific host directory into the container. Use for development (live code reloading) or sharing config files. Avoid in production containers. - tmpfs mounts (
docker run --tmpfs /tmp myapp) — In-memory only. Cleared when container stops. Use for sensitive data (secrets, tokens) that should not touch disk.
Container Security Hardening
Docker security is tested in every Senior DevOps interview. Here is the complete checklist I use at real production container security reviews:
- Never run as root — Add
USER 1001to your Dockerfile. Verify withdocker inspect --format='{{.Config.User}}' image:tag. - Use minimal base images — Alpine, distroless, or slim variants. Fewer packages = smaller attack surface. Distroless images have no shell at all, making container breakouts much harder.
- Read-only root filesystem — Run with
--read-onlyflag. Mount specific writable paths as volumes. Prevents malware from persisting to the container filesystem. - Drop capabilities — Run with
--cap-drop ALLand add back only what is needed. Most applications need zero Linux capabilities. - Scan images with Trivy —
trivy image --exit-code 1 --severity HIGH,CRITICAL myimage:tag. Run this in every CI pipeline. Exit code 1 fails the build on findings. - Pin image versions —
FROM node:20.11-alpine3.18notFROM node:latest. Unpinned images introduce non-deterministic builds and can pull in breaking changes or vulnerabilities. - Use .dockerignore — Exclude
node_modules,.git,*.env, and build artifacts from the build context. Speeds up builds and prevents sensitive files from entering images accidentally.
Docker Compose for Local Development
Docker Compose orchestrates multi-container applications for local development. A single
docker-compose.yml defines your API server, database, cache, and message broker.
One command starts the entire stack: docker compose up -d.
Interview Q&A
dive to inspect layer contents and find waste.docker image prune (dangling images only), docker system prune (stopped containers + dangling images + unused networks), docker system prune -a (everything not used by a running container — use carefully). In CI, always clean up after builds to prevent disk exhaustion on runners.🐳 Explore Docker on the Interactive Mind Map
See how Docker connects to Kubernetes, JFrog, GitHub Actions, Jenkins, and Trivy — with real commands and interview Q&A.
Open Interactive Mind Map Next: Kubernetes Guide →Once you understand Docker containers, the natural next step is container orchestration — learn how to manage them at scale with Kubernetes →
📩 Get Free DevOps Interview Notes
Cheat sheets, real commands, interview Q&As — free.
No spam · Follow @master.devops for daily tips