Frontend Labs
⋯

2. Docker architecture and core CLI

2.1 The moving parts

Piece Role
docker CLI client; talks to the daemon over a Unix socket or TCP
dockerd the daemon: images, networks, volumes, the API
BuildKit the build engine behind docker build/docker buildx (parallel stages, cache mounts, secrets, multi-arch)
containerd image pull/unpack, container lifecycle
registry stores images: Docker Hub, GHCR, ECR, GAR, ACR, Harbor

War story: access to /var/run/docker.sock is root on the host. Anyone who can docker run -v /:/host owns the machine. Teams that mount the socket into CI jobs or "monitoring" containers have handed out root. Treat the socket like an SSH key to root.

2.2 The 20 commands you will use daily

# images
docker pull nginx:1.27-alpine
docker images                                  # or: docker image ls
docker image history nginx:1.27-alpine         # layers and their sizes
docker image inspect nginx:1.27-alpine | jq '.[0].Config'
docker rmi <image>                             # remove
docker image prune -a                          # remove unused images

# containers
docker run -d --name web -p 8080:80 nginx:1.27-alpine   # detached, port 8080 -> 80
docker ps                                      # running; -a for all
docker logs -f --tail 100 web                  # follow logs
docker exec -it web sh                         # shell inside a running container
docker stop web                                # SIGTERM, then SIGKILL after 10s
docker kill web                                # SIGKILL now
docker rm -f web                               # stop + remove
docker inspect web | jq '.[0].State'           # status, exit code, OOMKilled flag
docker stats                                   # live CPU/mem/net/io per container
docker top web                                 # processes inside, seen from the host
docker cp web:/etc/nginx/nginx.conf ./         # copy files out (or in)

# housekeeping
docker system df                               # what is using disk
docker system prune                            # remove stopped containers, dangling images, unused networks

2.3 The run flags that matter in production

docker run -d \
  --name orders \
  --restart unless-stopped \           # auto-recovery: restart on crash and after daemon restart
  --memory 256m --memory-swap 256m \   # hard limit, no swap
  --cpus 0.5 \                         # CFS quota: half a core
  --pids-limit 200 \                   # fork-bomb protection
  --read-only --tmpfs /tmp \           # immutable root filesystem
  --cap-drop ALL \                     # no Linux capabilities
  --security-opt no-new-privileges \   # setuid binaries can't escalate
  --user 65532:65532 \                 # non-root
  --health-cmd 'wget -qO- http://localhost:8080/readyz || exit 1' \
  --health-interval 10s --health-retries 3 \
  -e DATABASE_URL \                    # pass through from your shell, not hard-coded
  -p 127.0.0.1:8080:8080 \             # bind to localhost only, not 0.0.0.0
  ghcr.io/acme/orbit-orders:1.4.2

Restart policies: no (default), on-failure[:max], always, unless-stopped. This is single-host auto-recovery. Kubernetes replaces it with controllers (§22).

Best practice: publish ports to 127.0.0.1 on dev machines and servers. -p 5432:5432 on a cloud VM binds to every interface, and Docker's iptables rules bypass ufw. Many leaked databases were exposed exactly like this.


Generated from real-life-k8s-guide.md · 8 Oct 2026 16:36