🐳 Docker Visual Guide

Every command explained with a diagram showing exactly what happens under the hood.

Images Containers Volumes Networking Docker Compose
πŸ“¦

Fundamentals

What is Docker? β€” core concept

Your code+ dependencies wrap Docker Imageportable snapshot run Containerrunning instance push/pull DockerHubimage registry Works identically on any OS β€” laptop, CI server, cloud

Image vs Container

ImageStatic blueprintRead-only layersStored on disk β†’ run β†’ ContainerRunning instanceWritable layer on topIsolated process

Container vs VM

ContainerShares host kernelStarts in msMBs in size Virtual MachineFull OS per VMStarts in minutesGBs in size
πŸ—

Architecture

Docker Engine β€” three components

Docker CLIuser types commands REST API Docker Daemon (dockerd)manages all Docker objectsimages Β· containers Β· networksvolumes Β· background service Container Runtimecreates / runs containers CLI β†’ REST API β†’ Daemon β†’ Runtime β€” the complete call chain

Docker Image Layers β€” how caching works

FROM python:3.11 RUN pip install… COPY . /app CMD ["python","app.py"] Layer stack (bottomβ†’top) βœ… Layer 1 (base image): cached β€” reused βœ… Layer 2 (pip install): cached β€” reused πŸ”„ Layer 3 (COPY): changed β€” rebuilds πŸ”„ Layer 4 (CMD): changed β€” rebuilds ↑ Put slow installs EARLY for max cache hits
πŸ“

Dockerfile

All Dockerfile instructions β€” what each does

FROMBase image to start from. Must be first. FROM python:3.11-slim WORKDIRSet working directory (creates if absent). WORKDIR /app COPYCopy files from host to image. COPY requirements.txt . RUNExecute command during build (creates a layer). RUN pip install -r requirements.txt CMDDefault command on start β€” overrideable at runtime. CMD ["python","app.py"] ENTRYPOINTAlways runs β€” not easily overridden. ENTRYPOINT ["gunicorn"] ENVSet environment variable in image. ENV NODE_ENV=production ARGBuild-time variable (not available at runtime). ARG VERSION=1.0 EXPOSEDocument which port the app listens on. EXPOSE 8080

CMD vs ENTRYPOINT β€” the difference

CMD onlyCan be overriddendocker run img echo hi→ runs "echo hi"CMD replaced entirely ENTRYPOINT onlyAlways runsdocker run img app.py→ python app.pyarg appended Both (recommended)ENTRYPOINT = fixed binaryCMD = default argsCMD overrideableENTRYPOINT stays fixed

Production Dockerfile example (multi-stage)

# ── Stage 1: build ─────────────────────────────────── FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt # ── Stage 2: final (tiny) image ────────────────────── FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local # only runtime deps COPY . . ENV PATH=/root/.local/bin:$PATH \ PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 EXPOSE 8000 USER nobody # never run as root HEALTHCHECK --interval=30s --timeout=5s \ CMD curl -f http://localhost:8000/health || exit 1 CMD ["gunicorn","--bind","0.0.0.0:8000","app:app"]
Multi-stage build: build tools stay in Stage 1. Only the runtime dependencies reach the final image β€” dramatically smaller size.
πŸ–Ό

Image Commands

docker build -t myapp:v1 .

Dockerfile+ source code Build enginereads instructions Layer 1 Layer 2 Layer 3 myapp:v1tagged image ready

The . = build context (current dir). -t tags the image. Each Dockerfile instruction = one cached layer.

docker images Β· docker rmi Β· docker image prune Β· docker history

Local image store nginx:latest myapp:v1 <none> dangling image ← docker images (lists all) ← docker rmi myapp:v1 ← docker image prune removes this docker history myapp:v1 β†’ shows all layers CMD ["python","app.py"] 0B COPY . /app 2.3MB RUN pip install … 48.1MB FROM python:3.11-slim 97.8MB
🟒

Container Commands

docker ps / docker ps -a β€” list containers

CONTAINER ID IMAGE STATUS PORTS NAMES a3f2b1c9d4e5 nginx:latest Up 3 hours 0.0.0.0:80->80/tcp webserver 9b8c7d6e5f4a myapp:v1 Exited (0) β€” myapp only with -a ↑

docker ps = only running. docker ps -a = all including stopped.

Container state machine β€” start / stop / pause / rm

created start running stop stopped rm removed restart paused pause unpause docker start|stop <name> docker pause|unpause <name> docker rm <name> docker rm -f (force) docker restart <name>
πŸš€

docker run Flags

-d detached Β· -it interactive Β· -p port Β· -v volume Β· -e env Β· --name Β· --rm

-ddetachedbackground -itinteractive+ TTY shell -p 8080:80host:containerport binding -v vol:/pathmount volumeor bind mount -e KEY=valenvironmentvariable --name myapphuman-readablecontainer name --rmauto-deleteon exit --network mynetattach to customDocker network --restart policyalways / unless-stoppedon-failure / no
docker run -d --name myapp --rm -e DB=postgres -v pgdata:/data -p 8080:80 --restart unless-stopped nginx

-p host:container β€” port mapping visualised

Browserlocalhost:8080 Host machine :8080host port -p maps :80container port nginx in containerlistening on :80 docker run -p 8080:80 nginx
πŸ”

Debug Commands

docker logs -f <container>

containerstdout / stderr [INFO] Server started :8000 [INFO] Request GET /api [ERROR] DB timeout! [INFO] Retrying in 2s… your terminaldocker logs -f

Flags: -f follow live Β· --tail 50 last 50 lines Β· --since 5m last 5 minutes Β· --timestamps show time

docker exec -it <container> /bin/bash

running container PID 1: main process NEW: /bin/bash docker exec -it exec spawns a NEW process inside the container's namespace Main process (PID 1) unaffected

docker stats Β· docker top Β· docker diff Β· docker cp Β· docker inspect

docker statslive CPU, RAMnet I/O docker topprocesses insidecontainer docker diffA=added C=changedD=deleted docker cpcopy files in/outany container docker inspectfull JSON configenv, mounts, network
πŸ’Ύ

Volumes

Named volume vs Bind mount vs tmpfs β€” three storage types

container /data named volumeDocker-managed disk-v mydata:/data bind mounthost filesystem path-v $(pwd):/app tmpfsRAM only β€” ephemeral--tmpfs /cache

docker volume create / ls / inspect / rm / prune

createnew volume lslist all inspectshow mountpoint rmdelete one pruneremove unused prefix: docker volume ...
🌐

Networking

Default bridge vs Custom bridge β€” DNS difference

default bridge β€” no DNS by name web db 172.17.0.3:5432 must use IP ❌ custom bridge β€” DNS works βœ… web db db:5432 name = hostname βœ… docker network create mynet docker run --network mynet ...

Network drivers at a glance

DriverDescriptionUse case
bridgeDefault. Virtual network, container DNS on custom bridgesMulti-container single host
hostShares host's network β€” no isolationHigh-performance, no port mapping
noneNo networking β€” fully isolatedBatch jobs, security-sensitive
overlaySpans multiple Docker hosts (Swarm)Distributed / clustered apps
macvlanAssigns MAC address, appears as physical deviceLegacy apps needing direct net access
☁️

Registry / DockerHub

docker tag Β· docker push Β· docker pull β€” the full flow

Your machinemyapp:v1 (local) tag + push DockerHub Registryuser/myapp:v1user/myapp:latestnginx:1.25postgres:15 pull Prod serverdocker pull + run docker tag myapp:v1 user/myapp:v1 docker push user/myapp:v1
πŸ”„

Full Lifecycle

Dockerfile β†’ Image β†’ Container β†’ Cleanup β€” end to end

Dockerfilewrite build instructions docker build -t app:v1 . Image: app:v1stored locally docker run -d -p 8080:80 app:v1 Container: runningserving on :8080 logsdebug execshell in docker stop myapp Container: stoppedstill on disk docker rm myapp Container: removeddocker rmi app:v1 β†’ image gone

docker system prune β€” full cleanup

stopped containersdangling images unused networksbuild cache docker system pruneall gone Β· disk freed -a = also unused images --volumes = volumes too

Quick reference β€” all commands

CategoryCommandWhat it does
Imagesdocker imagesList all local images
docker build -t name:tag .Build image from Dockerfile
docker rmi <image>Delete an image
docker image pruneRemove dangling images
Containersdocker run -d -p 80:80 nginxRun detached with port mapping
docker ps / ps -aList running / all containers
docker stop / start <name>Stop / start container
docker rm <name>Remove container
Debugdocker logs -f <name>Stream container logs
docker exec -it <name> bashShell into container
docker statsLive CPU/RAM usage
docker inspect <name>Full JSON config
Volumesdocker volume create mydataCreate named volume
docker volume ls / pruneList / remove unused volumes
Networksdocker network create mynetCreate custom bridge network
docker network lsList all networks
Registrydocker login / logoutAuthenticate to DockerHub
docker push user/img:tagPush image to registry
docker pull <image>Pull image from registry
Systemdocker system prune -aRemove all unused resources
docker system dfShow disk usage