Docker Images & Commands "Bible"
This guide serves as a definitive reference for Docker CLI commands and Image internals. It goes beyond docker run to cover the lifecycle, inspection, and system maintenance commands used by Platform Engineers.
1. Docker Images Internals
A Docker image is a read-only template used to create containers. It is built up from a series of layers.
The Layer System (UnionFS)
Each instruction in a Dockerfile creates a layer.
- Base Layer: The OS filesystem (e.g.,
FROM ubuntu:22.04orFROM alpine:3.18). - Intermediate Layers: Added by commands like
RUN,COPY,ADD. - Layer Caching: Docker caches layers. If you change line 3 of your Dockerfile, only line 3 and subsequent lines are rebuilt. Lines 1-2 come from the cache (Speed!).
Order matters! Put frequently changing instructions (like COPY . .) at the bottom of the Dockerfile. Put stable instructions (like RUN apt-get install) at the top.
The Build Context
When you run docker build ., the . represents the Context. Docker sends everything in that directory to the daemon.
- Use
.dockerignore: Always use a.dockerignorefile to excludenode_modules,.git, or secrets. Sending 500MB ofnode_modulesto the daemon slows down builds significantly.
Example .dockerignore:
# Dependencies and build artifacts
node_modules
.git
*.md
.env
.env.*
# Avoid sending secrets or large unrelated dirs
secrets/
*.log
Inspect layer sizes (find fat layers):
docker history --no-trunc <image>
Sample output:
IMAGE CREATED CREATED BY SIZE
abc123 2 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon…"] 0B
def456 2 days ago /bin/sh -c #(nop) EXPOSE 80 0B
789ghi 2 days ago /bin/sh -c apt-get update && apt-get insta… 120MB
...
Largest layers are usually RUN steps; optimize those first (multi-stage, combine RUN, clean caches).
Multi-Stage Builds
Use one stage to build artifacts and a second, minimal stage to run them; only the final stage layers appear in the image.
# Stage 1: Build
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp main.go
# Stage 2: Run (Distroless/Alpine)
FROM alpine:latest
WORKDIR /root/
COPY /app/myapp .
CMD ["./myapp"]
Result: A 10MB image instead of a 800MB Golang SDK image.
Build options (production & CI):
# Build a specific stage in multi-stage Dockerfile
docker build --target builder -t myapp:builder .
# Pass build-time variables (Dockerfile: ARG VERSION=1.0)
docker build --build-arg VERSION=2.0 -t myapp:2.0 .
# No cache (fresh build; use in CI when cache is unreliable)
docker build --no-cache -t myapp:v1 .
Image digest vs tag (immutability):
- A tag (e.g.
myapp:latest) is mutable; the same tag can point to different digests over time. - A digest (e.g.
myapp@sha256:abc123...) is immutable. Pinning by digest in production ensures the exact image revision is used regardless of tag updates.
docker pull nginx:1.25
docker images --digests nginx
# REPOSITORY TAG DIGEST
# nginx 1.25 sha256:1b...
# Run by digest:
docker run nginx@sha256:1b...
2. The Command Bible
A. Lifecycle Management (The Basics)
| Command | Description |
|---|---|
docker run -d --name web nginx | Run container in background (detached). |
docker run -it ubuntu bash | Run interactive shell. |
docker run --rm busybox | Automatically remove container when it exits. |
docker run --memory 512m --cpus 0.5 nginx | Resource limits (cgroups): cap memory and CPU. Matches K8s resources.limits. |
docker run --read-only -v /tmp/app:/data myapp | Read-only root FS; only /data writable (security). |
docker stop web | Graceful shutdown (SIGTERM). Waits 10s. |
docker kill web | Immediate shutdown (SIGKILL). |
docker rm -f web | Force remove a running container. |
docker ps -a | List all containers (running & stopped). |
docker rename old new | Rename a container. |
B. Image Management
| Command | Description |
|---|---|
docker build -t myapp:v1 . | Build an image from current directory. |
docker tag myapp:v1 repo/myapp:v1 | Retag an image for a registry. |
docker push repo/myapp:v1 | Upload to registry. |
docker pull nginx:alpine | Download from registry. |
docker images | List local images. |
docker rmi <image_id> | Remove an image. |
docker save -o img.tar myapp:v1 | Export image to a tarball (offline transfer). |
docker load -i img.tar | Import image from tarball. |
C. Inspection & Debugging (Advanced)
| Command | Usage |
|---|---|
docker inspect | docker inspect --format='{{.State.Pid}}' web Extract specific JSON fields. |
docker logs | docker logs -f --tail 100 web Follow logs, show last 100 lines. |
docker diff | docker diff web See file changes (Added, Changed, Deleted). |
docker top | docker top web See running processes inside the container. |
docker events | docker events Stream real-time events from the daemon (creates, dies, OOMs). |
docker port | docker port web Show port mappings. |
docker stats | docker stats web (no stream) or docker stats (live) CPU/memory usage (from cgroups). |
docker system df | Disk usage: images, containers, volumes, build cache. |
Sample docker inspect --format (get PID / IP for debugging):
docker inspect --format '{{.State.Pid}}' web
# 12345
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
# 172.17.0.2
Sample docker diff output:
A /tmp/newfile
C /etc/nginx/nginx.conf
D /var/cache/nginx/...
A=Added, C=Changed, D=Deleted in the container layer vs image.
D. Interaction
| Command | Description |
|---|---|
docker exec -it web sh | Start a new process (shell) inside running container. |
docker cp file.txt web:/tmp | Copy file from Host -> Container. |
docker cp web:/tmp/file.txt . | Copy file from Container -> Host. |
Debugging a broken image (no shell or wrong entrypoint):
# Override entrypoint to get a shell (use image's shell: sh, bash, or /bin/sh)
docker run -it --entrypoint /bin/sh myapp:broken
# Or with Alpine-based images:
docker run -it --entrypoint sh myapp:broken
Use this to inspect filesystem, test commands, or verify env before fixing the Dockerfile.
E. System Maintenance (Pruning)
Docker objects accumulate quickly. Use these commands to reclaim disk space.
prune commands delete data permanently.
docker container prune: Remove all stopped containers.docker image prune: Remove dangling images (untagged,<none>).docker image prune -a: Remove all unused images (even tagged ones not used by running containers).docker volume prune: Remove all unused volumes. (Dangerous! Database data can be lost if volume is not mounted).docker system prune: Removes stopped containers, unused networks, and dangling images. Add-ato include all unused images.
Check disk usage before pruning:
docker system df
Sample output:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 12 3 4.2GB 2.8GB (66%)
Containers 5 1 100MB 80MB (80%)
Local Volumes 3 1 500MB 200MB (40%)
Build Cache 45 0 1.1GB 1.1GB (100%)
Then use docker system prune -a (with care) or docker image prune -a to reclaim.
F. Networking (Quick Reference)
docker network ls: List networks.docker network create my-net: Create a bridge network.docker run --net my-net ...: Attach container to network.docker network connect my-net web: Connect a running container to a network on the fly.docker network inspect my-net: See which containers are connected & their IPs.