Digital Product Engineering7.6 Docker & Containerization
VOL. VII · CH. 7.6 · SOFTWARE ENGINEERING

Docker & Containerization

The technology behind "it works on my machine" no longer being an acceptable excuse.

DivisionDevOps / Infrastructure
DifficultyIntermediate
Prerequisites1.6
Related7.7 7.8
2 min read · 364 words

7.6.1Definition

Containerization packages an application together with everything it needs to run — dependencies, system libraries, runtime — into a single, portable unit called a container. Docker is the dominant tool for building, running, and sharing containers, ensuring the exact same environment runs identically on a developer's laptop, a CI pipeline, and a production server.

7.6.2Why It Exists

Before containerization, "it works on my machine" was a genuine, common failure — subtle differences in installed library versions or OS configuration between environments caused bugs that only appeared in production. Docker exists to eliminate that entire category of problem by packaging the application's complete runtime environment once and running that identical package everywhere, rather than each environment maintaining its own separately-configured setup.

7.6.3Core Concepts

  • Image — a built, immutable snapshot of an application and its environment, defined by a Dockerfile.
  • Container — a running instance of an image, isolated from the host system and other containers.
  • Dockerfile — the text file defining exactly how an image is built, step by step, making the environment reproducible from source.
  • Registry — a storage/distribution system (Docker Hub, a private registry) for sharing built images between environments.

7.6.4Common Mistakes

  • Bloated images including unnecessary build tools or files in the final image, increasing size and attack surface for no runtime benefit.
  • Running containers as root by default, unnecessarily widening the security impact if the container is compromised.
  • Baking secrets directly into an image, where they persist in image layers even if later "removed" in a subsequent instruction.
  • No explicit version pinning for base images, causing a rebuild months later to silently pull a different, potentially incompatible base.

7.6.5Best Practices

  • Use multi-stage builds to keep final images minimal, excluding build-only dependencies.
  • Run containers as a non-root user unless there's a specific reason not to.
  • Inject secrets at runtime via environment variables or a secrets manager, never baked into the image itself.
Real-World ExampleMost modern CI pipelines (7.5) run each build inside a fresh, identical Docker container, guaranteeing that a test passing in CI reflects exactly the same environment the application will run in production, closing the "works on my machine" gap entirely.