The core idea
Nearly every Docker command has the same shape:
The most common commands also have older short forms. docker ps is docker container ls, docker images is
docker image ls, docker rmi is docker image rm. Both work; you'll see both in the wild.
The commands you'll actually use
| Task | Command |
|---|---|
| Run a container | docker run [flags] image [command] |
| List running containers | docker ps (add -a for stopped ones too) |
| Stop, start, restart | docker stop web, docker start web, docker restart web |
| Remove a container | docker rm web (add -f to stop it first) |
| See logs | docker logs -f --tail 50 web |
| Run a command inside | docker exec -it web sh |
| Live resource use | docker stats |
| Everything about it | docker inspect web |
| List images | docker images |
| Download, upload | docker pull nginx:alpine, docker push ghcr.io/you/api:1.0 |
| Build an image | docker build -t my-api . |
| Remove an image | docker rmi my-api |
| Disk usage | docker system df |
| Clean up | docker system prune |
docker run, flag by flag
docker run has dozens of flags, but these cover most days:
docker run \
-d \
--name api \
-p 8080:3000 \
-e NODE_ENV=production \
-v api-data:/data \
--rm \
my-api:1.0| Flag | Means |
|---|---|
-d | detached: run in the background and print the container ID |
--name api | a name to use instead of the random one Docker picks |
-p 8080:3000 | host port 8080 forwards to container port 3000 |
-e KEY=value | set an environment variable |
-v api-data:/data | mount the volume api-data at /data (04.02 Volumes) |
--rm | delete the container when it exits |
-it | interactive with a terminal; use it for shells, not servers |
Anything after the image name replaces the image's default command: docker run --rm -it ubuntu bash.
run, start and exec
These three trip people up because they all sound like "make it go":
docker runcreates a new container from an image and starts it.docker startstarts an existing, stopped container again, with the same writable layer.docker execruns an extra process inside a container that's already running.
You run docker run -it ubuntu bash, create a file, then type exit. What state is that container in?
Finding things out
Two habits save a lot of guessing. Read logs before anything else, and use inspect with --format to pull out one
field instead of scrolling through JSON:
$ docker logs --tail 20 web$ docker inspect --format '{{.State.Status}} {{.State.ExitCode}}' webexited 137$ docker inspect --format '{{.NetworkSettings.IPAddress}}' web
An exit code of 137 means the container was killed (01.03 Under the hood: namespaces and cgroups).
Cleaning up
Docker never deletes anything on its own, so disk usage grows. See where it went, then prune:
$ docker system dfTYPE TOTAL ACTIVE SIZE RECLAIMABLEImages 14 3 4.2GB 3.1GB (73%)Containers 9 2 180MB 160MB (88%)Local Volumes 5 2 1.1GB 600MB (54%)Build Cache 61 0 2.3GB 2.3GB$ docker system prune
Example output. docker system prune removes stopped containers, unused networks, dangling images and build cache.
It does not remove volumes unless you add --volumes, and only removes images without a tag unless you add -a.
Both of those flags can delete things you want, so read the prompt before saying yes.
Do each of these and predict the result before you press enter:
$ docker run -it --name box ubuntu bash$ touch /keep-me && exit$ docker ps -a --filter name=box$ docker start -ai box$ ls /keep-me$ exit$ docker rm box$ docker system df
The file survives the stop and start because it's the same container. It's gone only after docker rm.
STUCK? ▸
If docker start -ai box says the container doesn't exist, you probably ran the first command with --rm. Leave it off for this exercise.
Recap
Interview questions
What's the difference between docker run, docker start and docker exec?
A CI server running Docker is out of disk. How do you find what's using space and reclaim it safely?