Skip to main content

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.04 or FROM 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!).
Optimization Strategy

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 .dockerignore file to exclude node_modules, .git, or secrets. Sending 500MB of node_modules to 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 --from=builder /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)

CommandDescription
docker run -d --name web nginxRun container in background (detached).
docker run -it ubuntu bashRun interactive shell.
docker run --rm busyboxAutomatically remove container when it exits.
docker run --memory 512m --cpus 0.5 nginxResource limits (cgroups): cap memory and CPU. Matches K8s resources.limits.
docker run --read-only -v /tmp/app:/data myappRead-only root FS; only /data writable (security).
docker stop webGraceful shutdown (SIGTERM). Waits 10s.
docker kill webImmediate shutdown (SIGKILL).
docker rm -f webForce remove a running container.
docker ps -aList all containers (running & stopped).
docker rename old newRename a container.

B. Image Management

CommandDescription
docker build -t myapp:v1 .Build an image from current directory.
docker tag myapp:v1 repo/myapp:v1Retag an image for a registry.
docker push repo/myapp:v1Upload to registry.
docker pull nginx:alpineDownload from registry.
docker imagesList local images.
docker rmi <image_id>Remove an image.
docker save -o img.tar myapp:v1Export image to a tarball (offline transfer).
docker load -i img.tarImport image from tarball.

C. Inspection & Debugging (Advanced)

CommandUsage
docker inspectdocker inspect --format='{{.State.Pid}}' web
Extract specific JSON fields.
docker logsdocker logs -f --tail 100 web
Follow logs, show last 100 lines.
docker diffdocker diff web
See file changes (Added, Changed, Deleted).
docker topdocker top web
See running processes inside the container.
docker eventsdocker events
Stream real-time events from the daemon (creates, dies, OOMs).
docker portdocker port web
Show port mappings.
docker statsdocker stats web (no stream) or docker stats (live)
CPU/memory usage (from cgroups).
docker system dfDisk 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

CommandDescription
docker exec -it web shStart a new process (shell) inside running container.
docker cp file.txt web:/tmpCopy 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.

Data Loss Risk

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 -a to 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.