Docker Roadmap
Containers From First Principles — Build, Debug and Ship With Confidence
Your Journey at a Glance
💡 How to use this roadmap
Work through each phase in order. Click on a skill to expand it — you'll find a description and curated resources. Don't rush; understanding beats speed. Complete one phase before moving to the next.
Foundations — What a Container Actually Is
Before any CLI flags: a container is an ordinary Linux process with a restricted view of the system. Build the mental model that makes every later behaviour predictable instead of magical.
Building Images — Dockerfiles & BuildKit
How layers, caching and the build context really work, and how to use the modern builder properly. This is where image size, build speed and most accidental credential leaks are decided.
Runtime — Networking, Storage & Process Behaviour
Connecting containers, keeping data alive, and understanding how a container starts and stops. Most 'it works locally but not in the container' bugs live in this phase.
Compose & Debugging Real Stacks
Running multi-container applications the way teams actually do, and building a repeatable method for diagnosing containers that will not start, will not connect, or will not stop.
Production Hardening & Supply Chain
What changes when the image leaves your laptop: least privilege, resource limits, secret handling, and knowing what is actually inside what you ship.
Scenarios — Real Incidents & Interview Discussions
Six incidents told end to end: the symptom, the investigation, the mechanism underneath, and how to discuss each one in an interview. This is where the previous five phases get exercised against real failures.
Roadmap Complete!
You now have the foundations of a production-ready Java engineer. Apply by building real projects.
Containerize and Harden a Multi-Service Application
Take a full stack — an HTTP API, a background worker, a relational database, a cache and a reverse proxy — from source to a locally reproducible, production-shaped Compose deployment, then justify every choice you made about size, privilege and persistence.
What you'll build
- Multi-stage, BuildKit-based images for the API and worker, with cache mounts for dependencies and a measured before/after image size
- Multi-platform build producing linux/amd64 and linux/arm64 from a single command
- HEALTHCHECK on every service, wired into Compose with depends_on: condition: service_healthy so startup order is correct rather than lucky
- Correct signal handling verified by observing graceful shutdown in the logs, not assumed from the Dockerfile
- Every service running as a non-root user with a read-only root filesystem and dropped capabilities
- Build-time credentials supplied via BuildKit secret mounts, proven absent from the final image using docker history
- Named volumes for database and cache state, with a documented restore-from-backup procedure you have actually run once
- A user-defined bridge network with service-name DNS, and no ports published except the proxy's
- Memory and CPU limits on each service, plus a deliberate test that triggers an OOM kill so you recognise exit code 137
- A Docker Scout scan and an attached SBOM, with a short written triage of any findings you chose not to fix
Tech stack
Key highlights
- ✦Every claim is verified with a command rather than assumed from the config file
- ✦Covers the three failure classes that hurt most in production: image bloat, lost state, and credentials in layers
- ✦Produces a stack you can hand to a teammate and have running with one command