Docker Deep Dive ยท Nigel Poulton ยท Complete Reference

Docker Reference
Guide

Complete reference covering containers, images, networking, volumes, Compose, and the Docker engine internals โ€” from zero to production.

Docker Engine Images & Layers Containers Dockerfile Compose Networking Volumes
CH 01

Virtualization & History

Types of Virtualization

๐Ÿ”ง HW-Level Virtualization

  • Network Virtualization
  • Storage Virtualization
  • Server Virtualization (VMs)

๐Ÿ“ฆ OS-Level Virtualization

  • Application Virtualization
  • Containers (Docker)
  • Shares host OS kernel

Evolution Timeline

EraTechnologyProblem SolvedDrawback
Bad Old DaysPhysical serversโ€”1 app per server, huge waste
VMware EraHypervisor / VMsMultiple apps per serverVM overhead (OS per VM, licenses)
Container EraLinux cgroups + namespacesLightweight isolationLinux-only initially
Docker Era (2013)Docker EngineEasy containerizationโ€”
Mac Containers? macOS has no native container primitives. Docker Desktop on Mac runs containers inside a lightweight Linux VM (HyperKit/Virtualization.framework). Kubernetes is also available as a single-node cluster via Docker Desktop.
CH 02

Docker โ€” The Technology & The Company

๐Ÿข Docker, Inc. (The Company)

  • Originally dotCloud (PaaS provider)
  • Built on Linux containers
  • Renamed Docker, Inc. in 2013
  • Products: Docker Desktop + Docker Hub
  • Open source on GitHub

โš™๏ธ Docker Technology (The Stack)

  • Runs on Windows and Linux
  • Create, manage, orchestrate containers
  • Three main components: Runtime, Daemon, Orchestrator

Docker Architecture

Docker Architecture
Docker Architecture: Shows the three-layer stack โ€” runtime (runc + containerd), daemon (dockerd), and the orchestrator (Swarm). The daemon exposes a REST API consumed by the client CLI.
ComponentBinaryRole
Low-level RuntimeruncOCI-compliant. Creates/starts/stops containers. Builds OS constructs (namespaces, cgroups).
High-level RuntimecontainerdManages runc. Pulls images, handles networking & volumes. CNCF open-source project.
Daemon / EnginedockerdExposes Docker REST API. Manages images, volumes, networks. Top-level orchestration.
OrchestratorSwarmNative cluster management. Clusters called swarms.

Open Container Initiative (OCI)

A governance council responsible for standardizing low-level container infrastructure. Two key specs:

  • image-spec โ€” defines what a container image is
  • runtime-spec โ€” defines how to run a container
CH 03

Installing Docker

๐Ÿ–ฅ๏ธ Docker Desktop

  • Windows 10 / macOS
  • Single-engine Docker
  • Docker Compose included
  • Single-node Kubernetes cluster

๐Ÿง Server Installs

Install on Ubuntu (Linux)

# 1. Remove old versions
  $ sudo apt-get remove docker docker-engine docker.io containerd runc

  # 2. Install prerequisites
  $ sudo apt-get update
  $ sudo apt-get install ca-certificates curl gnupg lsb-release

  # 3. Add Docker GPG key
  $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

  # 4. Add Docker repository
  $ echo "deb [arch=$(dpkg --print-architecture) \
    signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
    https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

  # 5. Install Docker Engine
  $ sudo apt-get update
  $ sudo apt-get install docker-ce docker-ce-cli containerd.io

  # 6. Verify
  $ sudo docker --version
  $ sudo docker info

Post-install: Avoid sudo

# Check current groups
  $ sudo getent group
  $ groups

  # Add user to docker group
  $ sudo usermod -a -G docker <username>
  $ groups   # verify
CH 04

The Big Picture โ€” Ops & Dev Perspectives

๐Ÿ› ๏ธ Ops Perspective

  • Download images from registries
  • Start / stop / delete containers
  • Log into running containers
  • Run commands inside containers
  • List and inspect containers

๐Ÿ’ป Dev Perspective

  • Clone repo with Dockerfile
  • Build image from Dockerfile
  • Run container from image
  • Test application
  • Push to registry

Ops Quick Commands

# Confirm installation
  $ docker version

  # Pull image
  $ docker image pull ubuntu:latest

  # Launch interactive container
  $ docker container run -it ubuntu:latest /bin/bash

  # Exit without terminating
  Ctrl-PQ

  # Attach to running container
  $ docker container exec -it <name> bash

  # Stop / Start / Delete
  $ docker container stop <name>
  $ docker container start <name>
  $ docker container rm <name>

Dev Quick Commands

# Clone repo
  $ git clone https://github.com/nigelpoulton/psweb.git

  # Inspect Dockerfile
  $ cat Dockerfile

  # Build image
  $ docker image build -t test:latest .

  # Run containerized app with port mapping
  $ docker container run -d \
    --name web1 \
    --publish 8080:8080 \
    test:latest
CH 05

The Docker Engine โ€” Deep Dive

Docker Engine TLDR
Docker Engine Overview: The top-level architecture showing dockerd, containerd, and runc in layers. Each handles progressively lower-level container operations.
Docker Engine Deep Dive
Docker Engine Deep Dive: Detailed view of how the client CLI communicates with dockerd over a UNIX socket, dockerd calls containerd, and containerd spawns runc for each container creation event.

runc โ€” The OCI Layer

  • CLI wrapper, standalone container runtime tool
  • Only creates containers โ€” no long-running daemon
  • Reference implementation of the OCI runtime-spec
  • Also called "the OCI layer"

containerd

  • Background daemon process: ps -elf | grep containerd
  • Manages full container lifecycle: start | stop | pause | rm
  • Handles image pulls, volumes, networks
  • Initially by Docker, Inc. โ†’ donated to CNCF

Container Creation Flow

$ docker container run --name ctr1 -it alpine:latest sh
1
Docker client converts command into API payload and POSTs to /var/run/docker.sock (Linux) or //./pipe/docker_engine (Windows)
2
Docker daemon (dockerd) receives the request
3
Daemon calls containerd via gRPC
4
containerd converts the image into an OCI bundle and invokes runc
5
runc interfaces with OS kernel (namespaces, cgroups) and creates the container as a child process
6
runc exits. The shim takes over (keeps STDIN/STDOUT open, reports status to daemon)
Container creation flow
Container Creation Flow: The request travels from the CLI โ†’ dockerd โ†’ containerd โ†’ runc โ†’ OS kernel. After the container starts, runc exits and a shim process remains as the parent.

The Shim

A reduced version of containerd that stays running after runc exits:

  • Keeps STDIN/STDOUT streams open even after daemon restart
  • Reports container exit status back to the daemon
  • Enables "daemonless containers" โ€” you can upgrade dockerd without killing running containers

Process Summary

$ ps -elf | grep container
  # You'll see: dockerd, docker-containerd, docker-containerd-shim, docker-runc

Client โ†” Daemon Communication

ChannelSocket / PortSecurity
Local Linux/var/run/docker.sockIPC socket
Local Windows//./pipe/docker_engineNamed pipe
Remote (insecure)2375/tcpNone โ€” avoid in production
Remote (TLS)2376/tcpmTLS โ€” client + daemon certs
TLS Communication
TLS-Secured Client-Daemon Communication: When deploying Docker remotely, mutual TLS (mTLS) must be configured. Both the daemon and client present certificates signed by the same CA. Port 2376 is the standard TLS port.
CH 06

Images

What is an image? A read-only package containing application code, dependencies, and OS constructs required to run an app. Images are build-time constructs; containers are runtime constructs. Think of an image as a stopped VM template.
Images vs Containers
Images vs Containers: An image is a static blueprint stored in a registry. When you run an image, Docker adds a thin writable layer on top to create a container โ€” a live, running instance of that image.

Image Layers

A Docker image is a stack of loosely-connected read-only layers. Each layer is one or more files. Docker uses a storage driver to stack and merge layers into a single unified filesystem.

Image Layers
Image Layers: Each Dockerfile instruction that modifies the filesystem creates a new layer. Layers are identified by cryptographic hashes of their content. Unchanged layers are cached and reused.
Layer build example
Building Layers: Example of a Python app image built on Ubuntu 20.04. Layer 1 = Ubuntu base, Layer 2 = Python runtime added via RUN, Layer 3 = App source code via COPY. Each instruction = one layer.
OSStorage Drivers
Linuxoverlay2 (recommended), AUFS, devicemapper, btrfs, zfs
Windowswindowsfilter (NTFS)

Image Registry & Naming

Image Registry Structure
Registry โ†’ Repository โ†’ Tag Hierarchy: Docker Hub is the default registry. Each registry contains repositories. Each repository stores one or more tagged versions of an image. Format: registry/repo:tag
TypeURL PatternExample Pull
Officialhub.docker.com/_/<name>docker image pull nginx:latest
Unofficialhub.docker.com/r/<user>/<repo>docker image pull nigelpoulton/tu-demo:v2
3rd Party Registry<registry-host>/<repo>:<tag>docker image pull gcr.io/google-containers/git-sync:v3.1.5

Image Commands

# Pull image
  $ docker image pull alpine:latest
  $ docker image pull mongo:4.2.6
  $ docker image pull -a nigelpoulton/tu-demo  # all tags

  # List images
  $ docker image ls
  $ docker image ls --digests alpine

  # Inspect layers and metadata
  $ docker image inspect ubuntu:latest
  $ docker image history web:latest

  # Search Docker Hub
  $ docker search alpine --filter "is-official=true"

  # Delete images
  $ docker image rm <name>
  $ docker image rm $(docker image ls -q) -f  # delete all
  $ docker image prune       # remove unreferenced images
  $ docker image prune -a    # remove all dangling images

Image Digests (Content Addressable Storage)

Docker 1.10+ uses cryptographic content hashes (digests) to uniquely identify images. Use a digest to pull the exact image you expect โ€” immune to tag mutations.

$ docker image pull alpine
  $ docker image ls --digests alpine
  # Output shows sha256:... digest per image

Multi-Architecture Images

Multi-arch manifest lists
Multi-Architecture Manifests: A single image tag (e.g., alpine:latest) can support multiple CPU architectures and OS types. When you pull, Docker inspects your platform and fetches the correct variant from the manifest list automatically. All official images have manifest lists.
# Inspect manifest list
  $ docker manifest inspect golang

  # Build for a specific platform
  $ docker buildx build --platform linux/arm/v7 -t myimage:arm-v7 .

  # Create custom manifest list
  $ docker manifest create
CH 07

Containers

What is a container? A container is the runtime instance of an image. Instead of virtualizing hardware like VMs, containers share the host OS kernel. One image can spawn multiple containers simultaneously.

Containers vs VMs

VM Architecture
VM Architecture: Each VM contains a full OS guest on top of a hypervisor. The hypervisor performs hardware virtualization โ€” allocating virtual CPU, RAM, and disk to each VM. This causes significant overhead: memory, CPU cycles, licenses.
Container Architecture
Container Architecture: Containers run directly on the host OS kernel, isolated via Linux namespaces and cgroups. No guest OS = near-zero overhead. All containers share one kernel, dramatically reducing resource usage.
AttributeVirtual MachinesContainers
IsolationHardware (hypervisor)OS (namespaces + cgroups)
Startup TimeMinutesMilliseconds
Resource OverheadHigh (full OS per VM)Minimal
OS per instanceYesNo (shared kernel)
LicensesPer OSNone (shared)
Attack surfaceMultiple kernelsSingle kernel
PortabilityLarge images (GB)Small images (MB)

Container Lifecycle

# Start interactive container with name
  $ docker container run --name myapp -it ubuntu:latest /bin/bash

  # Flags
  -i    โ†’ Keep STDIN open (interactive)
  -t    โ†’ Allocate pseudo-TTY
  -d    โ†’ Detached mode (background)
  --name โ†’ Set container name

  # Exit without killing (detach)
  Ctrl-PQ

  # Attach to running container
  $ docker container exec -it <name> bash

  # Stop (sends SIGTERM, then SIGKILL after 10s)
  $ docker container stop <name>

  # Start stopped container
  $ docker container start <name>

  # Delete (must be stopped)
  $ docker container rm <name>

  # Force delete running container
  $ docker container rm -f <name>

  # Delete ALL containers
  $ docker container rm $(docker container ls -aq) -f
Killing the Main Process Kills the Container The process running as PID 1 inside the container is the main process. If it exits (via exit in bash), the container stops. Use Ctrl-PQ to detach without stopping it.

Restart Policies

$ docker container run --name <name> --restart always <image> <cmd>
PolicyRestarts on crash?Restarts after manual stop?Restarts after daemon restart?
alwaysโœ“ Yesโœ“ Yesโœ“ Yes
unless-stoppedโœ“ Yesโœ— Noโœ— No
on-failureโœ“ Yes (non-zero exit)โœ— Noโœ“ Yes

Real-World Examples

# Web server (nginx on port 80)
  $ docker container run -d --name webserver -p 80:80 nginx:latest

  # SQL Server (MSSQL 2019)
  $ docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=P@ssw0rd" \
    -e "MSSQL_PID=Express" \
    -p 1433:1433 \
    -d mcr.microsoft.com/mssql/server:2019-latest

Inspect a Container

$ docker container inspect <name>
  # Returns JSON with: Cmd, Entrypoint, Mounts, NetworkSettings, RestartCount, State...

Container Commands Reference

docker container run

Start a new container from an image

docker container ls [-a]

List running containers. Add -a for stopped too

docker container exec -it

Run a new process inside running container

docker container stop

Graceful stop (SIGTERM โ†’ SIGKILL)

docker container start

Restart a stopped container

docker container rm [-f]

Delete stopped (or force-delete running) container

docker container inspect

Full JSON config and runtime info

docker container logs

View container stdout/stderr logs

CH 08

Containerizing an Application

Containerizing = taking an application and configuring it to run as a container.

Containerizing workflow
Containerization Workflow: The process flows from source code โ†’ Dockerfile โ†’ docker image build โ†’ image in local cache โ†’ optional push to registry โ†’ container run. Each step builds on the previous.

Containerization Steps

1
Start with your application code and dependencies
2
Create a Dockerfile describing your app, its dependencies, and how to run it
3
Run docker image build to create the image
4
Optionally push the image to a registry
5
Run a container from the image

Dockerfile Instructions Reference

InstructionCreates Layer?PurposeExample
FROMYes (base)Set base image โ€” must be first instructionFROM alpine:latest
LABELNoAdd metadata (maintainer, version)LABEL maintainer="me@email.com"
RUNYesExecute shell command during buildRUN apk add nodejs npm
COPYYesCopy files from build context into imageCOPY . /src
ADDYesLike COPY but also unpacks archives and fetches URLsADD app.tar.gz /app
WORKDIRNoSet working directory for subsequent instructionsWORKDIR /src
EXPOSENoDocument which port the app listens onEXPOSE 8080
ENVNoSet environment variablesENV NODE_ENV=production
ENTRYPOINTNoSet default executable for the containerENTRYPOINT ["node", "./app.js"]
CMDNoDefault arguments to ENTRYPOINT (overridable)CMD ["--port", "8080"]
VOLUMENoDeclare mount point for persistent dataVOLUME /data
HEALTHCHECKNoDefine health check commandHEALTHCHECK CMD curl -f http://localhost/

Example Dockerfile (Node.js App)

# Base layer โ€” Alpine Linux
  FROM alpine

  # Metadata
  LABEL maintainer="nigelpoulton@hotmail.com"

  # Install runtime deps (creates new layer)
  RUN apk add --update nodejs nodejs-npm

  # Copy app source into image (creates new layer)
  COPY . /src

  # Set working directory
  WORKDIR /src

  # Install npm dependencies (creates new layer)
  RUN npm install

  # Document port
  EXPOSE 8080

  # Default app to run
  ENTRYPOINT ["node", "./app.js"]

Build, Tag, and Push

# Build image
  $ docker image build -t web:latest .

  # Verify
  $ docker image ls
  $ docker image inspect web:latest
  $ docker image history web:latest

  # Login to Docker Hub
  $ docker login

  # Tag (must include your account name)
  $ docker image tag web:latest yourusername/web:latest

  # Push
  $ docker image push yourusername/web:latest

  # Run from registry
  $ docker container run -d --name c1 -p 80:8080 yourusername/web:latest
Pushing to Docker Hub
Pushing Layers to Docker Hub: Only layers that differ from what's already in the registry are uploaded. Shared base layers (e.g., Alpine) are skipped if already present. This delta-push mechanism saves bandwidth.

Multi-Stage Builds

One Dockerfile with multiple FROM instructions. Each is a build stage. Final stage only copies what's needed โ€” keeping production image small.

FROM node:latest AS storefront
  WORKDIR /usr/src/atsea/app/react-app
  COPY react-app .
  RUN npm install
  RUN npm run build

  FROM maven:latest AS appserver
  WORKDIR /usr/src/atsea
  COPY pom.xml .
  RUN mvn -B -f pom.xml -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
  COPY . .
  RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package -DskipTests

  FROM java:8-jdk-alpine AS production
  RUN adduser -Dh /home/gordon gordon
  WORKDIR /static
  # Copy ONLY the built artifacts from previous stages
  COPY --from=storefront /usr/src/atsea/app/react-app/build/ .
  WORKDIR /app
  COPY --from=appserver /usr/src/atsea/target/AtSea-0.0.1-SNAPSHOT.jar .
  ENTRYPOINT ["java", "-jar", "/app/AtSea-0.0.1-SNAPSHOT.jar"]
  CMD ["--spring.profiles.active=postgres"]

Build Best Practices

PracticeHowWhy
Leverage build cacheOrder Dockerfile instructions from least-to-most changingCache hit = skipped layer = faster rebuild
Squash imagedocker image build --squashMerges all layers into one โ€” reduces final size, hides intermediate state
No recommended packagesapt-get install --no-install-recommendsOnly main dependencies installed, keeps image lean
Multi-stage buildsSeparate build and production stagesBuild tools don't end up in production image
Use .dockerignoreCreate .dockerignore fileExcludes unnecessary files from build context
Squashed image
Squashed Image: Left = standard layered image (each RUN creates a layer). Right = squashed image (all layers merged into one). Useful when intermediate layers contain secrets or sensitive build state that shouldn't be accessible.
CH 09

Deploying Apps with Docker Compose

What is Docker Compose? Compose lets you describe an entire multi-container app in a single declarative YAML file and deploy it with a single command. Originally "Fig" by Orchard, acquired by Docker in 2014. Standardized as the Compose Specification in 2020.

Example Microservices App

Services in a typical app:

  • Web front-end
  • Ordering service
  • Catalog service
  • Back-end database
  • Logging
  • Authentication
  • Authorization

Compose File Keys:

  • version โ€” Compose file format version
  • services โ€” Container definitions
  • networks โ€” Network definitions
  • volumes โ€” Volume definitions

docker-compose.yml Example

version: "3.8"
  services:
    web-fe:
      build: .                   # Build from Dockerfile in current dir
      command: python app.py
      ports:
        - target: 5000
          published: 5000
      networks:
        - counter-net
      volumes:
        - type: volume
          source: counter-vol
          target: /code

    redis:
      image: "redis:alpine"       # Pull from Docker Hub
      networks:
        counter-net:

  networks:
    counter-net:

  volumes:
    counter-vol:

Installing Compose on Linux

# Download binary
  $ sudo curl -L \
    https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-x86_64 \
    -o /usr/local/bin/docker-compose

  # Make executable
  $ sudo chmod +x /usr/local/bin/docker-compose

  # Verify
  $ docker-compose --version

Deploying & Managing a Compose App

# Deploy (build images + start containers)
  $ docker-compose up

  # Deploy in background
  $ docker-compose up -d

  # Use custom compose file name
  $ docker-compose -f prod-config.yml up

  # List containers in app
  $ docker-compose ps

  # List processes in each service
  $ docker-compose top

  # Stop without deleting
  $ docker-compose stop

  # Start stopped app
  $ docker-compose restart

  # Delete stopped app (keeps volumes!)
  $ docker-compose rm

  # Stop AND delete (preserves volumes + images)
  $ docker-compose down
Volumes persist across docker-compose down docker-compose down removes containers and networks but NOT volumes. To also delete volumes: docker-compose down --volumes

Compose Commands Summary

docker-compose up [-d]

Deploy the app (optionally in background)

docker-compose down

Stop + delete containers and networks

docker-compose stop

Stop containers without deleting

docker-compose restart

Restart stopped app

docker-compose rm

Delete stopped Compose app

docker-compose ps

List containers in the app

docker-compose top

Show processes running in each service

docker-compose logs

View aggregated logs from all services

CH 10

Docker Networking

Docker Networking Model
Docker Networking Architecture: Built on the Container Network Model (CNM). libnetwork is Docker's Go implementation of CNM, providing the control plane. Network drivers implement the data plane for each network type (bridge, overlay, macvlan, etc.).

Container Network Model (CNM) Building Blocks

๐Ÿ“ฆ Sandboxes

Isolated network stack per container. Contains Ethernet interfaces, ports, routing tables, and DNS config.

๐Ÿ”Œ Endpoints

Virtual network interfaces. Connect sandboxes to networks. One sandbox can have multiple endpoints.

๐ŸŒ Networks

Software implementation of an 802.1d switch. Groups of endpoints that can communicate with each other.

CNM Building Blocks
CNM Building Blocks: Sandboxes contain the network stack of a container. Endpoints are virtual NICs that attach a sandbox to a network. Multiple sandboxes on the same network can communicate via their endpoints.

Network Drivers

OSDriverUse Case
LinuxbridgeDefault. Single-host container-to-container communication
overlayMulti-host communication (Swarm)
macvlanConnect containers to existing VLANs with their own MAC
WindowsnatEquivalent of Linux bridge
overlayMulti-host
transparentEquivalent of macvlan
l2bridgeLayer 2 bridging

Single-Host Bridge Networks

Bridge network
Single-Host Bridge Network: Docker creates a virtual bridge (docker0 on Linux) that connects containers on the same host. All containers on the bridge can communicate. The bridge maps to the external network via NAT for outbound traffic.
# List all networks
  $ docker network ls

  # Inspect a network
  $ docker network inspect bridge

  # Check underlying Linux bridge
  $ ip link show   # Look for docker0

  # Create custom bridge network
  $ docker network create -d bridge localnet

  # Connect container to custom network
  $ docker container run -d --name c1 --network localnet alpine sleep 1d

  # Create c2 on same network โ€” can ping c1 by name
  $ docker container run -it --name c2 --network localnet alpine sh
  # ping c1   โ† works on user-defined networks (built-in DNS)
Default bridge vs User-defined bridge The default bridge network does NOT support DNS-based name resolution between containers. User-defined bridge networks DO. Always create a custom bridge network for inter-container communication by name.

Port Mapping

# Map host port 5000 โ†’ container port 80
  $ docker container run -d --name web \
    --network localnet \
    --publish 5000:80 \
    nginx

  # Verify port mapping
  $ docker port web
Port mapping
Port Mapping: Bridge networks are isolated from the outside world by default. Port mapping (-p host_port:container_port) creates a NAT rule so external traffic hitting the host port gets forwarded to the container port.

MACVLAN โ€” Connecting to Existing Networks

The macvlan driver gives each container its own MAC address on the physical network โ€” making them appear as physical devices. Requires NIC in promiscuous mode.

MACVLAN networking
MACVLAN Network: Containers get their own MAC and IP on the existing VLAN. Useful for integrating with legacy applications that expect network-level identities. Containers appear as physical hosts to the rest of the network.
# Create MACVLAN network
  $ docker network create -d macvlan \
    --subnet=10.0.0.0/24 \
    --ip-range=10.0.0.0/25 \
    --gateway=10.0.0.1 \
    -o parent=eth0.100 \
    macvlan100

  # Run container on MACVLAN
  $ docker container run -d --name mactainer1 \
    --network macvlan100 \
    alpine sleep 1d

Service Discovery

Service Discovery
Service Discovery: Docker's built-in DNS resolves container names to IPs within the same network. Each container has a local DNS resolver (127.0.0.11) that forwards queries to Docker's internal DNS server. Scope is network-level โ€” containers on different networks cannot resolve each other by name.
# Custom DNS and search domain
  $ docker container run -it --name c1 \
    --dns=8.8.8.8 \
    --dns-search=example.com \
    alpine sh

Networking Commands

docker network ls

List all networks

docker network create

Create a new network

docker network inspect

Detailed config of a network

docker network prune

Delete all unused networks

docker network rm

Delete specific network

docker port <container>

Show port mappings

CH 11

Volumes & Persistent Data

๐Ÿ“ Non-Persistent (Ephemeral)

  • Lives in the container's writable layer
  • Created when container is created
  • Deleted when container is deleted
  • Managed by storage driver (overlay2 on Ubuntu)
  • Linux: /var/lib/docker/<storage-driver>/
  • Windows: C:\ProgramData\Docker\windowsfilter\

๐Ÿ’พ Persistent (Volumes)

  • Independent objects, not tied to container lifecycle
  • Survive container deletion
  • Can be mapped to external storage (SAN, NAS, cloud)
  • Sharable across multiple containers / hosts
  • Recommended way to persist data in Docker
Non-persistent container storage
Non-Persistent Storage: Every container gets a thin read-write layer on top of its image. This is the "ephemeral" storage. It's created with the container and destroyed with it. Managed by the storage driver (e.g., overlay2).
Volume persistent storage
Persistent Volume Storage: A volume is a separate object stored outside the container's writable layer. It's mounted into the container filesystem at a specified path. Deleting the container doesn't touch the volume or its data.

Creating and Managing Volumes

# Create a volume (using local driver by default)
  $ docker volume create myvol

  # List volumes
  $ docker volume ls

  # Inspect volume
  $ docker volume inspect myvol
  # Key fields: Mountpoint, Driver, Scope

  # Delete specific volume
  $ docker volume rm myvol

  # Delete ALL unused volumes (use with caution!)
  $ docker volume prune

Volume Inspect Output

[
      {
          "CreatedAt": "2020-05-02T17:44:34Z",
          "Driver": "local",
          "Labels": {},
          "Mountpoint": "/var/lib/docker/volumes/myvol/_data",  โ† host path
          "Name": "myvol",
          "Options": {},
          "Scope": "local"   โ† only this host can access it
      }
  ]

Using Volumes with Containers

# Mount volume into container
  $ docker container run -dit \
    --name voltainer \
    --mount source=bizvol,target=/vol \
    alpine

  # Write data to the volume
  $ docker container exec -it voltainer sh
    # echo "persistent data" > /vol/file1
    # cat /vol/file1
    # exit

  # Delete the container
  $ docker container rm voltainer -f

  # Volume and data still exists!
  $ docker volume ls
  $ ls -l /var/lib/docker/volumes/bizvol/_data/

  # Attach same volume to new container
  $ docker run --name hellcat \
    --mount source=bizvol,target=/vol \
    alpine sleep 1d

Volumes in Dockerfiles

# Declare a volume mount point in Dockerfile
  VOLUME /data
  # Note: host path cannot be specified in Dockerfile โ€” only container mount point

Sharing Volumes Across Cluster Nodes

Shared storage across nodes
Shared Storage Across Nodes: The local driver stores data on the Docker host. For multi-host sharing (e.g., in Swarm), third-party volume plugins (available on Docker Hub) integrate with cloud storage, SAN, or NAS โ€” enabling containers on different hosts to share the same volume data.

Volume Commands Reference

docker volume create

Create a new named volume

docker volume ls

List all volumes on this host

docker volume inspect

Show detailed volume info including host mountpoint

docker volume prune

Delete all unused volumes โ€” irreversible!

docker volume rm

Delete specific named volume

docker plugin install

Install third-party volume drivers from Docker Hub

docker plugin ls

List installed plugins

โŒ˜

Master Command Cheatsheet

Images

CommandDescription
docker image pull <repo>:<tag>Download image from registry
docker image pull -a <repo>Download ALL tags of an image
docker image lsList images in local cache
docker image ls --digestsShow image digests (hashes)
docker image inspect <image>Full metadata and layer info
docker image history <image>Show build history and layer sizes
docker image build -t <name>:<tag> .Build image from Dockerfile
docker image tag <src> <dst>Create additional tag for image
docker image push <repo>:<tag>Push image to registry
docker image rm <image>Delete image
docker image pruneRemove unreferenced images
docker image prune -aRemove all dangling images
docker manifest inspect <image>Inspect multi-arch manifest list
docker buildx build --platform <arch>Build for specific CPU architecture
docker search <term>Search Docker Hub

Containers

CommandDescription
docker container run -it <image>Run interactive container
docker container run -d <image>Run detached (background)
docker container run --name <n>Set container name
docker container run -p host:contPort mapping
docker container run --restart alwaysAuto-restart policy
docker container run --network <net>Connect to specific network
docker container run --mount source=vol,target=/pathMount a volume
docker container ls [-a]List running [+ stopped] containers
docker container exec -it <name> bashShell into running container
docker container stop <name>Graceful stop (SIGTERM)
docker container start <name>Restart stopped container
docker container rm [-f] <name>Delete container
docker container rm $(docker container ls -aq) -fDelete ALL containers
docker container inspect <name>Full configuration JSON
docker container logs <name>View logs

Compose

CommandDescription
docker-compose up [-d]Start all services (optionally detached)
docker-compose downStop + remove containers and networks
docker-compose stopStop without removing
docker-compose restartRestart stopped services
docker-compose psList containers in app
docker-compose topShow processes per service
docker-compose logsAggregate logs
docker-compose rmDelete stopped app

Networking

CommandDescription
docker network lsList networks
docker network create -d bridge <name>Create bridge network
docker network inspect <name>Inspect network details
docker network pruneRemove unused networks
docker network rm <name>Delete a network
docker port <container>Show port mappings

Volumes

CommandDescription
docker volume create <name>Create named volume
docker volume lsList all volumes
docker volume inspect <name>Inspect volume (shows host path)
docker volume rm <name>Delete volume
docker volume pruneDelete all unused volumes

System

CommandDescription
docker versionClient and server version info
docker infoSystem-wide info (registry, driver, etc.)
docker loginAuthenticate with Docker Hub
docker system pruneRemove all unused objects
service docker statusCheck Docker service status (Linux)
systemctl is-active dockerCheck if Docker daemon is active
ps -elf | grep containerdSee containerd/runc processes
ip link showSee Docker bridge interfaces (docker0)

Based on Docker Deep Dive by Nigel Poulton ยท Docker Hub ยท Docker Docs ยท OCI