Docker

Docker packages an application together with its dependencies and runtime into a container — an isolated process that behaves identically on a laptop, a CI runner, and a production server. It's the technology that turned "works on my machine" from an excuse into a non-issue.

Launched in 2013, Docker made Linux container technology accessible to mainstream developers with a simple CLI, a standard image format, and a registry (Docker Hub). Containers share the host's Linux kernel (unlike VMs, which each run their own), so they start in seconds and use minimal resources, and Docker now underpins modern CI/CD, orchestration, and cloud-native development.

TL;DR

Quick Example

A multi-stage Dockerfile keeps build tooling out of the final image, shrinking it and reducing attack surface:

Core Concepts

💡 Containers aren't VMs — they share the host kernel via cgroups (resource limits) and namespaces (isolation), which is why they're so lightweight. Images are immutable (you build new ones, not modify), and data is ephemeral without volumes.

Architecture

Variants

Ecosystem

Docker Engine is open-source (Apache 2.0); Docker Desktop requires a paid subscription for larger enterprises (open alternatives: Podman, Rancher Desktop).

Performance & Security

Performance: image size (large images slow builds/deploys), layer ordering (put frequently-changing files last for cache hits), and bind-mount I/O on macOS/Windows are the usual pain points. Use multi-stage builds, .dockerignore, and minimal base images.

Security: run as non-root, scan images for CVEs, pin tags, drop capabilities and use a read-only filesystem, never mount the Docker socket unless required, and never bake secrets into images (they're visible in docker history). See Container Security.

Comparison

VMs win for strong isolation and running different OSes; Kubernetes wins for production microservices, auto-scaling, and self-healing. See Kubernetes and Podman.

Best Practices

Common Mistakes

Using the latest tag in production

Baking secrets into the image

Treating a container like a VM

FAQ

What's the difference between a container and a VM?

A VM virtualizes hardware and runs a full guest OS with its own kernel; a container shares the host kernel and isolates only the process. Containers are far lighter and faster to start, but offer weaker isolation than VMs — a different security model.

Docker or Kubernetes — which do I need?

They solve different problems. Docker builds and runs containers; Kubernetes orchestrates many containers across many machines (scaling, self-healing, rolling updates). Use Docker (and Compose) for development and simple deployments; add Kubernetes when you need production orchestration at scale.

Why use multi-stage builds?

To keep build-time tooling (compilers, dev dependencies) out of the final image. You build in one stage and copy only the artifacts into a slim runtime stage, producing smaller, faster, more secure images.

How do I handle secrets in Docker?

Never put them in the image or Dockerfile — they persist in layers and docker history. Inject them at runtime via environment variables, a secrets manager, or BuildKit's --secret for build-time needs. See Secrets Management.

How do I make my images smaller?

Use a minimal base (slim, Alpine, or distroless), multi-stage builds, a .dockerignore, and combine/order layers well. Tools like dive show what's bloating each layer.

Related Topics

References