Docker — Core Concepts

The Problem Docker Was Built to Solve

In 2013, Solomon Hykes gave a five-minute demo at PyCon that showed Docker for the first time. The core pitch was embarrassingly simple: software should work the same everywhere it runs. That demo launched one of the fastest-adopted developer tools in history — Docker hit 100 million downloads in its first year.

The problem it attacked is called environment inconsistency. A Node.js app might need Node version 18 but the server has version 16. A Python library might depend on a specific version of a C++ library that doesn’t exist on the target machine. A configuration file might be missing. The list of ways software breaks in new environments is endless.

The old solution was virtual machines (VMs): spin up a full emulated computer with its own operating system, install everything fresh. This works, but it’s slow to start (minutes), huge in size (gigabytes), and wasteful — you’re running an entire operating system just to support your app.

Docker took a different angle.

Containers vs. Virtual Machines

Virtual MachineDocker Container
Startup time1–5 minutesUnder 1 second
Size1–20 GB50–500 MB typically
IncludesFull OSJust the app + dependencies
IsolationHardware-levelProcess-level

Containers don’t emulate hardware. They run directly on the host operating system’s kernel but with their own isolated filesystem, processes, and network. The Linux kernel has two features that make this possible: namespaces (which create the illusion of isolation — the container thinks it’s alone on the machine) and cgroups (which limit how much CPU, memory, and disk a container can use).

The result: containers feel isolated like VMs but start as fast as normal programs.

Images vs. Containers

This distinction trips up most beginners.

An image is a blueprint — a snapshot of a filesystem at a specific moment. It’s read-only. Think of it like a class in object-oriented programming.

A container is a running instance of an image. You can run ten containers from the same image simultaneously, each doing something different, and modifying their own temporary filesystem without touching the original image. Like ten objects created from the same class.

Images are built in layers. If your image starts from Ubuntu, then adds Python, then adds your app — those are three layers. If you build a second image that also starts from Ubuntu and also adds Python but adds a different app, Docker is smart enough to reuse the Ubuntu and Python layers. This is why downloading Docker images is fast — you usually already have most of the layers cached locally.

The Dockerfile

You describe how to build an image using a Dockerfile — a plain text file with instructions:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]

Each line creates a new layer. FROM starts with an existing base image. RUN executes a command during the build. COPY copies files from your machine into the image. CMD tells Docker what to run when a container starts.

Run docker build -t my-app . and Docker executes these instructions top to bottom, producing an image tagged my-app.

The Registry: Sharing Images

Docker Hub is a public registry where anyone can store and share images. When you run docker pull postgres, Docker downloads the official PostgreSQL image maintained by the Postgres team. No installation wizard. No version conflicts. Just a working Postgres server, ready in under a minute.

Private registries (Amazon ECR, Google Artifact Registry, GitHub Container Registry) work the same way but with access control — your company’s images stay internal.

The Common Misconception

Most people assume Docker is primarily for deployment. It’s not — or rather, that’s only half of it. Developers use Docker heavily during local development. Instead of installing MySQL on your laptop (and potentially messing up your existing setup), you run:

docker run -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 mysql:8.0

You have a MySQL server running in 10 seconds. When you’re done, you docker stop it. Nothing was installed on your machine permanently. This changes how teams onboard new developers: instead of a 15-page setup guide, new engineers run docker compose up and the entire stack — app, database, cache, queue — starts locally in one command.

One thing to remember: An image is the recipe; a container is the meal. You can make a hundred meals from one recipe, throw them all away, and the recipe is untouched.

dockercontainersdevopsprogramminginfrastructure

See Also

  • Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.