Docker, one command per page
The twenty-seven commands that cover everything you do every day.
Know the command. Lose the fear.
Docker, one command per page
The twenty-seven commands that cover everything you do every day.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Command behaviour verified against the official Docker documentation: docs.docker.com
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Everyday
The seven commands that carry a normal day, and what each one really creates and leaves behind.
- 01docker run
- 02docker ps
- 03docker images
- 04docker pull
- 05docker logs
docker run creates a new container from an image and starts it, pulling the image first if it is missing. -d detaches, --name names it, and --rm removes the container automatically when it exits.
docker run
Let's say you've pasted a docker run line from a README fifty times and it worked. What it did: created a brand new container from the image and started it, downloading the image first if needed.
Nothing is reused from last time's container. Every run leaves a container behind, even after it exits. Add --rm on a scratch machine and it deletes itself on exit. Long-running services get a --name, so you can talk to them later.
Containers are disposable. Names are how you find them.
docker run -d --name web -p 8080:80 nginx:alpine
docker ps lists containers, running ones only by default. The -a flag adds the stopped containers, which is where forgotten ones pile up, and --filter narrows the list to what you name.
docker ps
Let's say a port is taken and nothing seems to be using it. The first move is docker ps, the list of what's actually running, with the names you'll use in stop, logs, and exec. It's also where a container's port mapping shows up.
The trap is what the list leaves out. ps hides the stopped containers, and they stay on disk forever until you remove them. ps -a shows the whole pile, which is how you find the six forgotten pgtest containers. Filters help when the pile is big: --filter name=web, --filter status=exited. Everything docker does next starts with reading this list.
Run it before you type anything else.
docker ps -a
docker images lists the top images on disk with their tags and sizes. Intermediate and dangling images stay hidden unless you pass -a, and listed sizes include shared parent layers.
docker images
Let's say the disk is filling and you suspect the images. docker images lists every top-level image with tag, ID and size. The reading half of housekeeping, and it costs nothing.
The list hides things: intermediate and dangling images only appear with -a, and <none> tags are usually old builds nobody renamed. Sizes look bigger than they are because images share base layers, stored once. Knowing what's on disk beats guessing at it.
Images share layers. The list under-reports the mess.
docker images
docker pull downloads an image from a registry one layer at a time, reusing any layer already on disk. With no tag it pulls latest, and --platform chooses the architecture.
docker pull
Let's say the demo starts in two minutes and the network picks now to die. docker pull downloads the image layer by layer and stores it locally, so run has nothing left to fetch.
Layers you already have are skipped, across versions and across images, which is why a refreshed tag pulls in seconds. No tag means latest, and latest on your laptop and latest next month are different images. --platform pins the architecture.
Pull early. Pin the tag.
docker pull nginx:alpine
docker logs shows what the main process printed to stdout and stderr. -f streams new lines as they arrive, --tail keeps it short, and it works on stopped containers too.
docker logs
Let's say the container starts and dies three seconds later. Read what it said first: docker logs shows everything the main process printed to stdout and stderr.
-f streams new lines, tail keeps it short, --since 30m is gold at 3am. Logs belong to the container, so a crashed container's last words are still there for the reading. Apps logging to a file inside the container lose the file with the container.
Logs first. Restarts second.
docker logs -f web
docker build turns a Dockerfile and a build context into an image. Unchanged instructions reuse cached layers, and everything after the first change rebuilds. -t names the result.
docker build
Let's say every build takes four minutes and you've stopped shipping small fixes. The cache is the way out: docker build reuses a layer for every instruction whose inputs haven't changed.
The moment one instruction changes, its layer rebuilds, and everything after it loses the cache too, changed or not. That's why dependency files come before source. -t names the result. Reordering the file turns four minutes into forty seconds, permanently.
Cache is earned by instruction order.
docker build -t myapp:1.0 .
docker compose up builds, creates, starts and attaches to every service in the Compose file, plus the network joining them. -d detaches so they keep running after the terminal closes.
docker compose up
Let's say local setup is five README steps. One compose file replaces it: services, ports, volumes, wiring. docker compose up builds, creates, starts and attaches to every service in one go.
-d detaches and leaves the stack running. The command is idempotent in the useful way: unchanged services stay up, changed ones get recreated. The hyphenated docker-compose is the old v1 binary; the space is the real spelling now.
One file, one command, the whole app.
docker compose up -d
docker system prune removes stopped containers, unused networks, dangling images and unused build cache in one go, asking first. -a widens images to all unused ones, --volumes adds anonymous volumes.
docker system prune
Let's say df says gigabytes are reclaimable. docker system prune clears stopped containers, unused networks, dangling images and build cache in one go, and asks before it touches anything.
-a widens images from dangling-only to every unused one. --volumes adds anonymous volumes, and there's no undo for data; Docker 23.0 stopped pruning them by default for exactly that reason. docker cp out anything you need before the y.
Read the prompt. It's a contract.
docker system prune -a