Docker basics
The Docker commands for images, containers, and Compose you'll reach for constantly — flags explained, not just listed.
Last updated
Images
| Command | What it does |
|---|---|
| docker pull nginx | Downloads an image from a registry — usually Docker Hub — without running it yet. |
| docker build -t myapp . | Builds an image from the Dockerfile in this folder and tags it myapp. |
| docker images | Lists every image you've pulled or built locally, with its size. |
| docker rmi myapp | Deletes a local image — fails if a container is still using it. |
| docker tag myapp myapp:v2 | Gives an image another name — the usual first step before pushing it to a registry. |
Containers
| Command | What it does |
|---|---|
| docker run -d nginx | Starts a container in the background and hands your terminal back immediately. |
| docker run -p 8080:80 nginx | Maps your machine's port 8080 to the container's port 80 — left side is yours, right side is theirs. |
| docker run -v ./data:/app/data nginx | Mounts a folder from your machine into the container — files survive even if the container doesn't. |
| docker ps | Lists running containers — add -a to see stopped ones too. |
| docker ps -a | Lists every container, running or not — where 'it disappeared' containers hide. |
| docker stop mycontainer | Asks a container to shut down gracefully, with a grace period before it's forced. |
| docker rm mycontainer | Deletes a stopped container — its filesystem is gone, but named volumes survive. |
| docker exec -it mycontainer bash | Opens an interactive shell inside a running container — for poking around live. |
| docker logs -f mycontainer | Streams a container's output live — the equivalent of tail -f for containers. |
| docker restart mycontainer | Stops then starts a container again — for when a service just needs a kick. |
Compose
| Command | What it does |
|---|---|
| docker compose up -d | Starts every service defined in docker-compose.yml, in the background. |
| docker compose down | Stops and removes everything compose started — containers, networks, the works. |
| docker compose logs -f | Streams logs from every service in the project, interleaved and labeled. |
| docker compose ps | Lists just this project's containers, not every container on the machine. |
| docker compose build | Rebuilds images for services that have a build: section, without starting them. |
Cleanup & inspect
| Command | What it does |
|---|---|
| docker system prune | Deletes stopped containers, unused networks, and dangling images in one pass. |
| docker system prune -a | The aggressive version — also removes any image not used by a running container. |
| docker volume ls | Lists named volumes — where data outlives a docker rm. |
| docker volume prune | Deletes ANONYMOUS volumes no container is using; add -a to include named ones (Docker 23+). |
| docker inspect mycontainer | Dumps everything Docker knows about a container as JSON — IP, mounts, env vars, all of it. |
| docker stats | A live view of CPU, memory, and network use per container — top, but for containers. |
| docker cp mycontainer:/app/log.txt . | Copies a file out of a container without needing to exec in first. |
Worth remembering
- →-p is host:container, always in that order — mixing it up is the single most common docker run mistake.
- →docker rm doesn't touch named volumes — that data survives until you docker volume rm it explicitly.
Questions
What is the difference between an image and a container?
An image is the immutable filesystem and metadata; a container is a running instance of one with a writable layer on top. Stopping a container does not remove it, which is why they accumulate.
Why is my image so large?
Usually build tooling left in the final layer. A multi-stage build compiles in one stage and copies only the artefact into a slim runtime image, which routinely cuts size by an order of magnitude.
Does docker system prune remove my data?
It removes stopped containers, unused networks and dangling images. Named volumes are kept unless you add --volumes, which is the flag to be careful with because it deletes data.
Why do file changes not appear in the container?
Because the image was built with a copy of the files. Mount the directory as a volume for development, or rebuild after each change — the second is why development in containers feels slow.
How do I see what went wrong in a failed container?
docker logs works on stopped containers as well as running ones, so the output survives the exit. For a container that will not start at all, override the entrypoint with a shell and look inside.