TL;DR
- Fifteen commands cover most daily Docker work: run, ps, stop, start, rm for container lifecycle; exec, logs, inspect for debugging; build, images, pull, rmi for images; compose up, compose down for multi-service apps; system prune for disk recovery.
- Reach for
docker runwhen you need a new container,docker startwhen you are resuming one that already exists, anddocker composewhen the app has more than one service. - The failure mode is not missing obscure flags. It is using
docker runfor everything, never pruning disk, and debugging production issues withoutdocker logsanddocker inspect. - Modern Docker uses the
docker composeplugin (V2). The standalonedocker-composebinary is legacy; examples below use the integrated command.
You cloned a repo with a Dockerfile and a compose.yml, ran one command from a blog post three months ago, and now you are staring at Error response from daemon: Conflict. The container name "/api" is already in use with no idea whether to remove, restart, or rebuild. Docker's CLI has hundreds of subcommands. You do not need hundreds. You need the small set that shows up in every standup, incident, and local dev session.
In this article, you will get 15 Docker commands ranked by how often working developers actually use them, with copy-paste examples, the flags that matter, and the mistakes each command helps you avoid.
Note
What you need: Docker Engine 24+ or Docker Desktop 4.25+ with the Compose V2 plugin (docker compose version should work). All examples assume a Linux or macOS shell. On Windows, use WSL2 or Git Bash for identical syntax.
Why most Docker cheat sheets fail you
Most cheat sheets list 40 commands alphabetically. That is fine as a poster. It is useless when a container exits immediately and you need logs, or when disk usage hits 100% and Docker refuses to build.
The 15 commands below are ordered by workflow, not alphabet. They are the overlap across Docker's official docs, production cheat sheets, and the commands teams re-type daily: lifecycle first, then debugging, then images, then Compose, then cleanup. If you internalize these, you can handle a new microservice repo in minutes instead of re-googling flags.
| Workflow | Commands | What you are trying to do |
|---|---|---|
| Run containers | run, ps, stop, start, rm | Create, list, pause, resume, and delete containers |
| Debug containers | exec, logs, inspect | Shell in, read output, read metadata |
| Manage images | build, images, pull, rmi | Build, list, download, and delete images |
| Multi-service apps | compose up, compose down | Start and stop stacks from YAML |
| Disk recovery | system prune | Reclaim space from orphaned objects |
Commands for running containers
These five commands cover the container lifecycle from first launch to removal.
1. docker run
docker run creates and starts a container from an image. It is the command you use when nothing exists yet.
The example below runs Nginx detached, maps host port 8080 to container port 80, names the container, and auto-removes it when it stops:
docker run -d \
--name web \
-p 8080:80 \
--rm \
nginx:1.25-alpineCommon flags worth memorizing:
-d: detached (background)-p HOST:CONTAINER: publish a port to your machine (see ports vs expose for when this differs from internal-only networking)--name: stable name forstop,logs, andexec--rm: delete the container on exit (great for one-off tests)-e KEY=val/--env-file .env: inject environment variables-v HOST_PATH:CONTAINER_PATH: bind-mount code or data for local dev
2. docker ps
docker ps lists running containers. Add -a to include stopped containers, which is what you need when something exited and you want its name back.
docker ps
docker ps -a --filter "name=web"Use --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" when the default table hides the port mapping you care about.
3. docker stop
docker stop sends SIGTERM and waits for graceful shutdown before SIGKILL. Use it instead of deleting a container when you plan to start it again.
docker stop web
docker stop -t 30 web # wait up to 30 seconds before SIGKILL4. docker start
docker start resumes a stopped container with the same filesystem, env, and name. It does not re-read your image or Dockerfile.
docker start web
docker start -a web # start and attach stdout/stderr to your terminal5. docker rm
docker rm deletes a stopped container. You cannot remove a running container unless you pass -f.
docker rm web
docker rm -f web # force-remove a running container
docker container prune # remove all stopped containers (narrower than system prune)Commands for debugging containers
When a container crashes on boot or behaves differently in Docker than on your host, these three commands are the first line of defense.
6. docker exec
docker exec runs a command inside a running container. The -it flags give you an interactive shell.
docker exec -it web sh
docker exec web nginx -t # run a one-off command without a shellIf exec fails with "container is not running," check docker ps -a and read docker logs first. The container likely exited before you tried to shell in.
7. docker logs
docker logs prints stdout and stderr from the container's main process. This is how you see stack traces, bind errors, and migration failures.
docker logs web
docker logs -f --tail 100 web # follow the last 100 lines live
docker logs --since 10m web # only the last 10 minutes8. docker inspect
docker inspect returns full JSON metadata: IP address, mount points, env vars, network mode, and health check state. Use --format to pull one field without scrolling.
docker inspect web
docker inspect --format '{{.State.Status}}' web
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' webCommands for building and shipping images
Images are the artifact docker run consumes. These four commands cover local builds and registry workflows.
9. docker build
docker build creates an image from a Dockerfile in the build context (usually .).
docker build -t myapp:local .
docker build -t myapp:local -f Dockerfile.prod .
docker build --no-cache -t myapp:local . # ignore layer cacheTag with a registry prefix before you push: myregistry.example.com/myapp:v1.0.
10. docker images
docker images lists images on your machine. Use it before rmi so you do not delete the wrong tag.
docker images
docker images myapp
docker images --filter "dangling=true" # untagged intermediate layers11. docker pull
docker pull downloads an image from a registry (Docker Hub by default). Pin a digest or version tag instead of latest in production pipelines.
docker pull nginx:1.25-alpine
docker pull myregistry.example.com/myapp:v1.012. docker rmi
docker rmi removes a local image. It fails if a running container still references that image unless you remove the container first.
docker rmi myapp:local
docker rmi -f myapp:local # force when multiple tags point at the same layer
docker image prune -a # remove images not used by any containerCommands for multi-container apps
Single-container tutorials hide the reality of modern apps: an API, a database, and a cache on a shared network. Compose encodes that stack in YAML so docker compose up replaces five manual docker run commands.
13. docker compose up
docker compose up reads compose.yml (or docker-compose.yml) and creates networks, volumes, and containers for every service.
docker compose up -d # detached
docker compose up -d --build # rebuild images before start
docker compose logs -f api # tail one service after startup14. docker compose down
docker compose down stops and removes containers, networks, and the default network created for the project. Add -v only when you intend to delete named volumes (database data).
docker compose down
docker compose down -v # also remove named volumes (destructive)Commands for reclaiming disk
Docker's layer cache and stopped containers accumulate fast on laptops and CI runners. When docker build fails with "no space left on device," this is the command you need.
15. docker system prune
docker system prune removes stopped containers, unused networks, dangling images, and build cache.
docker system prune # interactive prompt
docker system prune -f # skip prompt
docker system prune -a --volumes # aggressive: unused images + volumesStart with plain docker system prune. Escalate to -a only when you accept re-pulling images on the next build.
How to verify the workflow
Run this sequence once on a throwaway project to confirm the commands connect:
docker pull nginx:1.25-alpinedocker run -d --name verify-nginx -p 8080:80 nginx:1.25-alpinedocker psshowsverify-nginxwith0.0.0.0:8080->80/tcpcurl -I localhost:8080returns HTTP headers from Nginxdocker logs verify-nginxshows the Nginx access log line from your curldocker stop verify-nginx && docker rm verify-nginx
If you have a compose.yml in a repo, replace steps 2 through 6 with docker compose up -d, docker compose ps, docker compose logs, and docker compose down.
When these commands are not enough
These 15 commands assume single-host Docker Engine. They do not cover:
- Kubernetes:
kubectlreplaces most of this CLI once workloads move to a cluster. Docker Desktop still uses these commands locally before you push images. - Multi-platform builds:
docker buildx build --platform linux/amd64,linux/arm64is required when Apple Silicon laptops build images for AMD64 servers. - Secrets and production hardening: Swarm secrets, rootless Docker, and image signing live outside daily dev workflows but matter in production.
- Root cause inside the app:
docker logsshows that the process crashed. It does not replace a debugger inside your language runtime.
For networking decisions that affect -p and internal service communication, read Docker ports vs expose next.
For authoritative reference, see the Docker CLI documentation and the Compose file reference.

