Docker Command Reference
Docker has many commands, but most daily work uses a small, predictable set. A command reference matters because Docker objects are connected: images create containers, containers attach to networks and volumes, and registries store image layers behind tags and digests. This lesson organizes the commands by job so you can choose the right tool without memorizing the whole CLI.
Overview: How Docker commands work
The docker command is a client. On Linux it usually talks to the Docker Engine daemon through a Unix socket such as /var/run/docker.sock. On Docker Desktop for macOS and Windows, the client talks to a daemon running inside a small Linux VM. Either way, the commands you type ask the daemon to pull layers, create containers, mount filesystems, attach networks, collect logs, and push manifests to registries.
Docker commands mostly operate on five object types. An image is a read-only template made from stacked filesystem layers plus configuration such as CMD, ENTRYPOINT, ENV, USER, and exposed ports. A container is an instance of an image with a thin writable layer and, when running, a process. A volume is Docker-managed persistent storage. A network connects containers and provides DNS for container names or Compose service names. A registry stores compressed layer blobs and manifests; a tag points to a manifest, while a digest identifies exact image content.
Many commands have a noun-and-verb shape: docker image ls, docker container rm, docker volume inspect. Docker also keeps older shorthand commands such as docker ps, docker images, and docker rmi. Both forms are common. The newer object-oriented form is easier to discover because related operations sit under the same noun.
For multi-container projects, use docker compose, the modern Compose V2 subcommand. It reads a Compose YAML file, creates a project network, starts services, attaches named volumes, and lets services reach each other by service name. The old standalone docker-compose command exists in legacy environments, but new examples should use docker compose.
Syntax
docker [GLOBAL_OPTIONS] COMMAND [ARGUMENTS]
docker OBJECT COMMAND [OPTIONS] [ARGUMENTS]
docker compose [OPTIONS] COMMAND [ARGUMENTS]
| Form | Purpose |
|---|---|
docker --help |
Lists top-level commands and global options. |
docker COMMAND --help |
Shows options for one command, such as docker run --help. |
docker build -t NAME:TAG . |
Builds an image from the current directory as the build context. |
docker run [OPTIONS] IMAGE |
Creates and starts a new container from an image. |
docker ps -a |
Lists running and stopped containers. |
docker logs CONTAINER |
Prints container stdout and stderr captured by Docker. |
docker exec -it CONTAINER COMMAND |
Runs an extra process inside an existing running container. |
docker compose up -d |
Creates or updates a Compose application in the background. |
docker inspect OBJECT |
Prints detailed JSON metadata for images, containers, volumes, or networks. |
Examples
Build and run a small web image
FROM nginx:1.27-alpine
COPY ./site /usr/share/nginx/html
EXPOSE 80
Output:
Dockerfile saved. The image will contain static files from ./site and records port 80 as metadata.
This Dockerfile uses a pinned base image tag instead of nginx or latest, which makes rebuilds more predictable. The EXPOSE line documents that the container listens on port 80, but it does not publish the port to the host. Publishing happens when a container is started with -p or when Compose uses ports:.
docker build -t static-site:1.0 .
docker run --rm --name static-site -p 8080:80 static-site:1.0
Output:
[+] Building 4.1s (7/7) FINISHED
=> naming to docker.io/library/static-site:1.0
Serving content on http://localhost:8080
The build command sends the current directory as the build context, applies the Dockerfile, and tags the result. The run command creates a container from that image and maps host port 8080 to container port 80. The --rm flag removes the container when it exits, but it does not delete the image.
Inspect containers and read logs
docker ps --filter "name=static-site"
docker logs static-site
docker inspect --format '{{.State.Status}} {{.NetworkSettings.Ports}}' static-site
Output:
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
0b7a2d6f8c91 static-site:1.0 "/docker-entrypoint.…" Up 2 minutes 0.0.0.0:8080->80/tcp static-site
172.17.0.1 - - "GET / HTTP/1.1" 200 615
running map[80/tcp:[{0.0.0.0 8080}]]
docker ps is the quick view for container state. docker logs reads stdout and stderr captured by Docker; it does not read arbitrary files inside the container. docker inspect exposes the full metadata model, and --format lets you extract only the fields you need in scripts.
Use volumes and networks deliberately
docker network create app-net
docker volume create app-data
docker run -d --name redis-cache --network app-net redis:7.4-alpine
docker run --rm --name app-tools --network app-net -v app-data:/data alpine:3.20 sh -c "echo cached > /data/status.txt && cat /data/status.txt"
Output:
app-net
app-data
cached
The network command creates an isolated bridge network where containers can reach each other by name. The volume command creates Docker-managed storage that survives container removal. The final command mounts the volume at /data and writes a file there. If the container disappears, the named volume remains until you remove it with docker volume rm app-data.
Manage a project with Compose
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html:ro
cache:
image: redis:7.4-alpine
volumes: {}
Output:
compose.yml saved. The web service is published on host port 8080, and cache is reachable as hostname cache.
This Compose file runs a small web server and Redis cache. The bind mount maps a specific host directory into the web container as read-only, which is useful for local development. It is different from a named volume: a bind mount points to a host path you choose, while a named volume is managed inside Docker’s storage area.
docker compose up -d
docker compose ps
docker compose logs web
docker compose down
Output:
[+] Running 3/3
✔ Network reference_default Created
✔ Container reference-web-1 Started
✔ Container reference-cache-1 Started
NAME IMAGE STATUS PORTS
reference-web-1 nginx:1.27-alpine Up 0.0.0.0:8080->80/tcp
Compose groups resources under a project name, creates a default network, and starts services in dependency order when possible. down removes the project containers and network. It does not remove named volumes unless you add --volumes, which is important when data should survive restarts.
How it works step by step
- You type a command. The Docker CLI parses flags, reads your Docker context, and sends an API request to the daemon.
- The daemon resolves object names. For images, it checks local tags and may contact a registry. For containers, it finds the container ID behind a name.
- Images are pulled or built as layers. Docker reuses local layers when possible. During builds, each instruction creates or reuses a cached layer; a changed instruction invalidates that layer and every later layer.
- A container gets a writable layer. When
docker runcreates a container, Docker mounts the image layers read-only and adds a thin writable layer for container changes. - Runtime settings are applied. Docker attaches networks, mounts volumes or bind mounts, sets environment variables, configures port publishing, and starts the configured process.
- Output is captured. Stdout and stderr become
docker logs. Metadata becomes available throughdocker inspect. - Cleanup is explicit. Removing a container does not remove its image. Removing an image does not remove containers using it. Volumes also persist until removed.
Common Mistakes
Using a command that creates a new container when you meant to enter the old one
docker run -it static-site:1.0 sh
This creates a brand-new container from the image. It does not open a shell in the already running static-site container. Use docker exec when you need an extra process inside an existing running container.
docker exec -it static-site sh
Assuming EXPOSE publishes a port
FROM nginx:1.27-alpine
EXPOSE 80
This is only image metadata. It helps humans and tooling understand the intended port, but the host still cannot reach the container unless you publish the port with docker run -p 8080:80 nginx:1.27-alpine or Compose ports:.
Removing the wrong thing
docker rm static-site
docker rmi static-site:1.0
docker rm removes containers. docker rmi or docker image rm removes images. If a stopped container still references an image, Docker may refuse to remove the image until the container is removed. Volumes are separate again, so deleting a container does not automatically delete a named volume.
Depending on latest in automation
docker pull nginx:latest
docker run -d --name web nginx:latest
latest is a mutable tag, not a guarantee of freshness or safety. In CI/CD and production, prefer explicit version tags and record the image digest after testing.
Best Practices
- Use
docker COMMAND --helpwhen checking flags; it is faster and more accurate than guessing. - Prefer explicit object names such as
--name static-site, volume names, and network names in examples, scripts, and runbooks. - Use pinned image tags for repeatable builds and deployments. Treat
latestas a convenience for experiments only. - Use
docker run --rmfor disposable one-shot containers, but avoid it for services whose writable layer you still need to inspect. - Publish ports explicitly with
-p host:containeror Composeports:; remember thatEXPOSEis documentation. - Use named volumes for persistent data and bind mounts for deliberate host-path sharing during development.
- Use
docker inspect --formatfor scripts instead of parsing human-oriented tables fromdocker ps. - Use
docker composefor multi-service local and CI workflows, not the legacydocker-composebinary. - Clean up carefully: inspect before using prune commands on shared machines because unused images, containers, networks, and volumes may still matter to someone else.
Practice Exercises
- A teammate says the app container is running, but the browser cannot reach it. Identify the commands you would use to check container status, published ports, and recent logs. Hint: start with
docker ps. - Create a command sequence for a disposable Redis test container on a custom network named
lab-net. Expected end state: the Redis container can be removed without affecting the network. - Given a Compose project with a
webservice, find the commands to start it in the background, view only that service’s logs, list project containers, and remove the project.
Summary
- The Docker CLI talks to the Docker daemon, which manages images, containers, networks, volumes, and registry communication.
- Images are read-only layered templates; containers are instances with a writable layer and runtime settings.
docker runcreates a new container, whiledocker execruns a command in an existing running container.docker logs,docker ps, anddocker inspectare the core troubleshooting commands.- Compose is the standard tool for multi-container projects and should be invoked as
docker compose. - Cleanup commands target different object types, so remove containers, images, networks, and volumes intentionally.
