Docker basics · Lesson 1 of 8 · about 12 minutes

What containers solve

Before running your first container, it helps to know the problem it fixes: an app that works on one machine and breaks on the next.

By the end you'll know

  • Why "it works on my machine" happens, and how containers end it
  • How a container differs from a virtual machine
  • The difference between an image and a container, the most important idea in this track
  • How to check that Docker is ready on your laptop

The problem: it works on my machine

You write an app on your laptop, and it runs perfectly. You copy it to a server, and it crashes. The server has a different version of Python. Or it's missing a library your app quietly depended on. Or a setting is different. None of that was in your code, so your code alone wasn't enough to run the app. It needed your whole laptop.

Every developer has said "but it works on my machine." The real problem is that an app isn't just its code. It's the code plus everything around it: the language version, the libraries, the system tools, the settings. Move the code without the rest, and you're hoping the next machine happens to match.

What a container does

A container packages your app together with everything it needs to run: the right language version, the libraries, the system tools. The package runs the same way on your laptop, on a coworker's laptop and on a server, because it brings its own surroundings with it.

Each container also runs isolated: it has its own files and its own view of the network, so two apps that need different versions of the same library can run side by side on one machine without stepping on each other.

Think of shipping containers. Before them, every ship was loaded by hand: barrels, sacks and crates of every shape, packed differently at every port. Then came one standard steel box. A crane doesn't care whether it holds shoes or coffee; every ship, train and truck is built to carry the same box. Software containers do the same thing for apps: whatever's inside, every machine knows how to run the box.

Containers and virtual machines

You may know virtual machines (VMs), which also let one computer run several separate systems. The difference is what each one carries:

Virtual machines compared with containersOn the left, three virtual machines run on one computer. Each one carries a full operating system of its own, on top of a hypervisor and the hardware. On the right, three containers run on one computer. They hold only their app and its libraries, and they share the computer's one operating system through a container engine such as Docker.Virtual machinesApp AApp BApp CFull OSits own copyFull OSits own copyFull OSits own copyHost OS and hypervisorHardwareContainersApp A+ its librariesApp B+ its librariesApp C+ its librariesContainer engine (Docker)Host OS: one kernel, shared by every containerHardwareEach VM carries a whole operating system. Containers share one, so they're smaller and start in seconds.
A virtual machine pretends to be a whole computer, with its own operating system. A container only packages the app and its libraries, and shares the operating system that's already running.
  • A virtual machine pretends to be a whole computer. Each one boots its own complete operating system, which takes gigabytes of disk and memory, and a minute or more to start.
  • A container only packages the app and what it needs. It shares the operating system's core, the kernel, with every other container on the machine. That makes it small, often tens of megabytes, and quick to start, often in under a second.

Neither replaces the other. In fact they're often used together: in the cloud, your containers usually run inside a virtual machine that someone else manages.

Images and containers

Two words you'll use in every lesson from here on:

  • An image is the package: your app and everything it needs, frozen into a file that doesn't change. You build it once.
  • A container is a running copy of an image. You can start many containers from one image, and each one runs on its own.
Think of a cookie cutter. The cutter is the image: you make it once, and it never changes. Each cookie is a container: you can make as many as you like from the same cutter, and eating one doesn't affect the others, or the cutter.

Here's the whole journey in one line, which the rest of this track walks through step by step:

Dockerfile (the instructions) → build → image → push to a registry → pull on another machine → run → container

A registry is a library of images, like Docker Hub, where you can download images other people built and share your own.

What Docker is

Docker is the most popular tool for building images and running containers. When people say "Docker", they usually mean the docker command plus the engine that runs containers behind it.

Docker didn't keep containers to itself, though. Images follow an open standard, so an image you build with Docker runs anywhere that understands that standard, including Kubernetes, which doesn't use Docker at all to run them. Learn Docker, and what you build carries over.

In my real setup

My API, CivicGrid, is written in Python. Its image holds a specific version of Python, every library the API uses at an exact version, and one system library it needs to talk to its database. The servers that run it don't need Python installed at all: everything the API needs is inside the image.

The same image runs on my laptop when I test it, and in my production cluster when I ship it. That's the "works on my machine" problem gone: if it works in the image, it works everywhere the image runs.

And if you've done the Kubernetes track, you've already been using Docker without thinking about it: kind runs each Kubernetes node as a Docker container.

When you don't need containers

Not everything needs a container. This website is a good example: it's a Next.js site on Vercel, and Vercel builds and runs it for me, so there's no image to make. Containers earn their keep when you run your own servers, run several services side by side, or need the exact same setup on every machine.

Get ready for Lesson 2

Lesson 2 has you running containers, so get Docker installed now:

Then check it's working:

BASH
docker version

You should see two sections, Client and Server. The client is the docker command you type; the server is the engine that actually runs containers. If you only see Client and an error about connecting, Docker isn't running yet: open Docker Desktop and wait for it to finish starting.

Check yourself

  1. Your app runs on your laptop but crashes on a server, and the code is identical. What's the most likely cause?

  2. What does a container package?

  3. Why do containers usually start much faster than virtual machines?

  4. What's the difference between an image and a container?

  5. You start three containers from the same image, and one of them deletes a file inside itself. What happens to the other two?

  6. You build an image with Docker. Where else can it run?

Key terms

  • Container: a running app, packaged with everything it needs, isolated from other containers on the same machine.
  • Image: the unchanging package a container starts from.
  • Virtual machine (VM): a whole pretend computer, with its own operating system.
  • Kernel: the core of an operating system. Containers on one machine share it.
  • Registry: a library of images to download from and share to, like Docker Hub.
  • Docker: the most popular tool for building images and running containers.

Go deeper