50 Docker Commands and Patterns for Developers
AI generated
Docker · Container · DevOps · CLI
50 Docker Commands and Patterns for Developers
from docker run to production-ready Compose stacks

Anyone who operates Docker purely by gut feeling loses time debugging and ends up with fragile images. These 50 essential Docker commands and patterns cover images, containers, volumes, networks and Compose, with concrete examples you can apply immediately in daily development work.

20 min read docker run · build · exec · inspect · Compose Docker 24+ · Docker Compose v2 · Linux · macOS

1. Why learning Docker commands systematically pays off

The Docker CLI is powerful, but it also runs deep. Many developers know a dozen Docker commands by heart and stumble on the rest. That costs time, especially when a container refuses to start, a volume stays empty, or a build unexpectedly takes an hour. Understanding the most important Docker commands and their options lets you narrow down problems systematically instead of deleting and restarting containers at random.

The Docker CLI is organized into logical groups: docker image, docker container, docker volume, docker network and docker compose. Each group has its own subcommands, and knowing this structure helps when exploring unfamiliar options with docker <group> --help. The following sections walk through the most important Docker commands in each group, with concrete examples and a focus on common developer mistakes that become instantly visible once you use the right command.

2. Building and managing images: the core of the workflow

The most important Docker command in the daily build workflow is docker build with targeted options. --no-cache forces a full rebuild without cached layers, which is useful for mysterious build failures that only occur in CI. --target builds a specific stage in a multi-stage Dockerfile, which lets you produce different images for testing, development and production from a single Dockerfile. --build-arg passes build-time arguments that are declared as ARG in the Dockerfile.

Three Docker commands are central to image management: docker images with --filter dangling=true lists untagged images that take up disk space. docker image history IMAGE shows the layer hierarchy with sizes, essential for understanding why an image is bigger than expected. docker image inspect IMAGE returns the full JSON manifest with environment variables, entrypoint, ports and labels. These three Docker commands replace a lot of guesswork around image problems with hard facts.


# Build with BuildKit enabled (default in Docker 23+)
DOCKER_BUILDKIT=1 docker build \
  --target production \
  --build-arg APP_VERSION=1.4.2 \
  --build-arg BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --tag myapp:1.4.2 \
  --tag myapp:latest \
  --file docker/Dockerfile \
  .

# Show layer sizes, find which step adds the most weight
docker image history myapp:1.4.2 --no-trunc --format "{{.Size}}\t{{.CreatedBy}}"

# Inspect the full image manifest (entrypoint, env, labels)
docker image inspect myapp:1.4.2 --format '{{json .Config}}' | jq .

# List dangling (untagged) images consuming disk space
docker images --filter "dangling=true" --format "{{.ID}}\t{{.Size}}"

# Save image as tar for air-gapped transfer
docker save myapp:1.4.2 | gzip > myapp-1.4.2.tar.gz
docker load < myapp-1.4.2.tar.gz

A common misunderstanding around Docker commands: docker build . sends the entire directory as the build context to the Docker daemon. Without a careful .dockerignore file, node_modules, .git and other large directories get shipped along, which slows down the build unnecessarily. The Docker command docker build --no-cache --progress=plain . shows the full build output with timestamps for every step, the fastest way to identify the slow step in a Dockerfile.

3. Starting, stopping and debugging containers

docker run is the most frequently used Docker command, yet hardly anyone knows all the important flags. --rm automatically deletes the container once it stops, useful for one-shot containers. -it opens an interactive terminal. --init starts a minimal init process as PID 1 that reaps zombie processes and forwards signals correctly. --read-only makes the container's filesystem read only and forces explicit volume mounts for any write operation, a simple security win.

For running containers, docker exec and docker logs are the central debugging Docker commands. docker exec -it CONTAINER sh opens a shell in a running container without a restart. docker logs --follow --since 5m CONTAINER shows the last 5 minutes of logs and streams new lines. docker top CONTAINER shows the processes inside the container. docker stats --no-stream gives a one-off snapshot of CPU and memory usage across all running containers, the fastest Docker command for resource diagnostics without external tools.


# Run a one-shot container: auto-remove, correct signal handling, read-only fs
docker run --rm --init --read-only \
  --tmpfs /tmp \
  --tmpfs /run \
  -e APP_ENV=production \
  -p 8080:80 \
  --name myapp-test \
  myapp:latest

# Open shell in running container for live debugging
docker exec -it myapp-test sh

# Stream logs from the last 10 minutes
docker logs --follow --since 10m --timestamps myapp-test

# Run a command as a specific user inside the container
docker exec -u www-data myapp-test php bin/console cache:clear

# Copy a file out of a container for inspection
docker cp myapp-test:/var/www/html/var/log/exception.log ./exception.log

# Check resource usage (one snapshot, no continuous refresh)
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"

4. Using volumes and bind mounts correctly

Volumes and bind mounts are conceptually different, but the Docker command flag -v serves both. A named volume (-v myvolume:/app/data) is managed by Docker and outlives the container lifecycle. A bind mount (-v ./src:/app/src) mirrors a host directory into the container, ideal for development, risky in production if host paths do not exist or have the wrong permissions. The Docker command --mount type=volume,src=myvolume,dst=/app/data is more explicit and allows additional options such as readonly.

Three Docker commands are especially useful for volume management: docker volume ls lists all volumes with their name and driver. docker volume inspect VOLUME shows the actual mount point on the host, important when you need to access volume data directly. docker volume prune deletes all unused volumes that are not attached to any container. For backups, the Docker command docker run --rm -v myvolume:/data -v $(pwd):/backup alpine tar czf /backup/data.tar.gz /data is the standard pattern: a temporary Alpine container mounts the volume and creates an archive.

5. Networks: connecting containers with each other

Docker networks are the most common source of confusion when getting started with Docker commands. The default bridge network does not support container name resolution: one container cannot reach another by name. User-defined bridge networks solve this problem: containers on the same network can address each other by name because Docker runs an internal DNS. The Docker command docker network create mynet creates such a network, and docker run --network mynet attaches a container to it.

The Docker command docker network inspect NETWORK shows all connected containers with their IP addresses and is the first tool to reach for when facing network issues. docker network connect NETWORK CONTAINER attaches a running container to a network after the fact, without a restart. For diagnosing network problems, the Docker command docker run --rm --network container:TARGETCONTAINER nicolaka/netshoot is a powerful tool: it starts a temporary container inside the network namespace of the target container with a full set of network tools such as tcpdump, nmap and dig.

6. Docker Compose: managing stacks declaratively

Docker Compose is no longer a standalone tool but a plugin (docker compose instead of docker-compose). The most important Docker command in the Compose context is docker compose up --watch, which uses Docker Compose Watch (since v2.22) to automatically sync changed files into running containers without requiring volume mounts. docker compose --profile dev up starts only the services assigned to the "dev" profile, enabling different service combinations for development, testing and production from a single compose.yaml.

For daily work with Compose, four Docker commands are indispensable: docker compose ps shows the status and health of all services. docker compose logs -f SERVICE streams the logs of a single service. docker compose exec SERVICE sh opens a shell in a running service. docker compose config resolves all extends, variables and overrides and shows the final configuration, ideal for debugging Compose files before starting the stack. The Docker command docker compose down -v stops the stack and simultaneously deletes all named volumes.


# Start stack with development profile, rebuild changed images
docker compose --profile dev up --build --remove-orphans

# Show rendered config (resolves variables, extends, overrides)
docker compose config

# Scale a specific service to 3 replicas
docker compose up --scale worker=3 -d

# Execute a one-off command in a running service
docker compose exec -it app php bin/magento cache:flush

# Follow logs from multiple services simultaneously
docker compose logs -f app db redis

# Tear down stack and remove named volumes (full reset)
docker compose down -v --remove-orphans

# Run a one-shot command without starting the full stack
docker compose run --rm app php bin/console doctrine:migrations:migrate

7. Inspection, logs and resource monitoring

The Docker command docker inspect is one of the most powerful tools available, yet it is rarely used to its full potential. With --format and Go template syntax, you extract single fields from the JSON output in a targeted way. docker inspect --format '{{.State.Health.Status}}' CONTAINER returns the health status. docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER returns the IP address. These Docker commands are more valuable in scripts than parsing the full JSON output with jq.

For resource monitoring, the Docker command docker events offers a real-time stream of all Docker events: container starts, stops, image pulls, volume mounts. With --filter type=container --filter event=die you can react specifically to crashed containers. docker system df shows an overview of the storage used for images, containers and volumes, the fastest Docker command for understanding why the Docker partition is filling up. docker system df -v prints the details per image and volume.

8. Cleanup: tidying up images, containers and volumes

Docker has a well-known tendency to eat up disk space through old images, stopped containers and orphaned volumes. The Docker command docker system prune cleans everything up in one go: stopped containers, unused networks, dangling images and the build cache. With --volumes, unused volumes are removed as well, use caution on development environments since persistent data can be lost. The --filter until=48h flag limits the cleanup to resources older than 48 hours.

For granular cleanup there are specific Docker commands: docker image prune -a deletes all unused images, including tagged ones. docker container prune deletes stopped containers. docker builder prune --keep-storage 5GB caps the BuildKit cache at 5 GB. In CI pipelines, docker image prune -a --filter until=1h is often run after the build to limit disk usage on the CI agent. The Docker command docker system prune -af --volumes as a weekly cron job on development machines keeps Docker installations lean.

9. Docker commands in direct comparison

Many tasks can be solved with different Docker commands, with substantial differences in efficiency and safety. Choosing the right command directly affects how quickly you resolve problems and how robust the setup ends up being.

Task Suboptimal Recommended command Benefit
Shell in a container docker run -it IMAGE bash docker exec -it CONTAINER sh Uses the running container, no new container needed
Finding an IP address docker inspect … | grep IPAddress docker inspect --format '{{.NetworkSettings…}}' Direct output, no grep parsing needed
Container name resolution docker network (default bridge) docker network create (user-defined) DNS between containers works automatically
Keeping the build context small No .dockerignore .dockerignore with node_modules, .git Noticeably faster builds, less network traffic
Storage overview du -sh /var/lib/docker docker system df -v Breakdown by images, volumes, cache

Choosing between docker run and docker exec is the most common mistake when diagnosing running containers. Starting a new container with docker run to inspect the state of a running container gives you an empty, fresh state, not the state of the problematic container. Only docker exec operates within the same namespaces as the running container. This distinction explains why many Docker commands for debugging only make sense with exec.

Mironsoft

Docker infrastructure, container stacks and CI/CD automation

Docker stacks that work reliably for your whole team?

We analyze existing Docker setups, identify fragile patterns and replace them with robust Docker commands and Compose configurations, complete with proper error handling and clean cleanup.

Docker review

Analysis of existing Dockerfiles and Compose configurations for weaknesses and optimization potential

Compose stack setup

Production-ready Docker Compose stacks with health checks, restart policies and secrets management

CI/CD integration

Integrating and optimizing Docker builds and deployments in GitLab CI, GitHub Actions or Jenkins

10. Summary

The 50 most important Docker commands and patterns cover every aspect of everyday container work: building images efficiently with multi-stage builds and targeted build args, starting containers safely with --init and --read-only, understanding volumes and networks instead of guessing. docker inspect --format replaces grep parsing with direct field extraction. docker compose config makes Compose configurations transparent before the stack is started. docker system df and system prune keep development machines and CI agents clean.

The biggest lever is combining these tools: using Docker commands for inspection and debugging systematically instead of blindly restarting containers. Anyone who consistently uses docker logs, docker exec, docker inspect and docker stats finds problems in minutes instead of hours. Adding a well-maintained .dockerignore, deliberate multi-stage builds and user-defined networks makes Docker setups not only faster but also considerably more maintainable across a team.

50 Docker Commands and Patterns, the essentials at a glance

Images & build

docker build --target for multi-stage builds, --no-cache for mysterious failures, image history for layer analysis, narrow down build problems systematically.

Containers & debugging

docker exec for a shell in a running container, logs --since for time-based logs, stats --no-stream for a resource overview.

Networks & volumes

User-defined networks for DNS resolution, named volumes for persistence, bind mounts only for development. network inspect for connectivity issues.

Cleanup & Compose

docker system prune for storage cleanup, compose config for configuration transparency, compose down -v for a full reset.

11. FAQ: Docker commands and patterns for developers

1Difference between docker run and docker exec?
docker run starts a new container from an image. docker exec runs a command inside a running container. Always use exec for debugging, run creates an empty new instance.
2Why is there no container name resolution on the default network?
The default bridge network has no internal DNS. User-defined networks automatically enable DNS, so containers can address each other by name.
3How do I keep the build cache clean?
docker builder prune --keep-storage 5GB. In CI: docker image prune -a --filter until=1h after the build. docker system prune -a for a full cleanup.
4What does --init do in docker run?
Starts tini as PID 1, forwards signals correctly and reaps zombie processes. Especially important for apps without their own signal handlers.
5Extracting an IP address by script?
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' CONTAINER, directly, without grep or jq.
6Named volumes vs. bind mounts?
Named volumes for persistence in production. Bind mounts for source code during development. Prefer named volumes in production, platform independent and managed by Docker.
7How do I shrink my Docker image?
Multi-stage builds, .dockerignore, combining RUN commands, Alpine base images. docker image history shows which layers take up the most space.
8What does docker system df show?
Storage usage broken down by images, containers, volumes and build cache. -v gives details per image and volume. The fastest overview when Docker storage is full.
9Starting only certain Compose services?
Profiles: mark services with profiles: [dev], run docker compose --profile dev up. Or directly: docker compose up app db, starts only the named services and their dependencies.
10Debugging network problems between containers?
docker network inspect NETWORK. For deeper analysis: docker run --rm --network container:TARGET nicolaka/netshoot, tcpdump, nmap and dig inside the target container's namespace.