Docker
Chapter 58: Docker - Complete Guide
Section titled “Chapter 58: Docker - Complete Guide”Mastering Container Technology for DevOps
Section titled “Mastering Container Technology for DevOps”58.1 Understanding Docker Architecture
Section titled “58.1 Understanding Docker Architecture”What is Docker?
Section titled “What is Docker?”Docker is an open platform for developing, shipping, and running applications using containerization technology. Containers are lightweight, standalone packages that include everything needed to run software: code, runtime, libraries, and settings.
Docker vs Traditional Virtualization+------------------------------------------------------------------+| || Traditional Virtual Machines || +----------------------------------------------------------+ || | +----------+ +----------+ +----------+ | || | | Guest OS | | Guest OS | | Guest OS | | || | +----------+ +----------+ +----------+ | || | | | | | || | v v v | || | +-----------------------------------------------+ | || | | Hypervisor (VMware, Hyper-V) | | || | +-----------------------------------------------+ | || | | | || | v | || | +-----------------------------------------------+ | || | | Hardware (CPU, RAM, Disk) | | || | +-----------------------------------------------+ | || | | || | Drawbacks: | || | - Heavy (full OS per VM) | || | - Slow to start | || | - Resource intensive | || +----------------------------------------------------------+ || || Docker Containers || +----------------------------------------------------------+ || | +----------+ +----------+ +----------+ | || | |Container | |Container | |Container | | || | +----------+ +----------+ +----------+ | || | | | | | || | v v v | || | +-----------------------------------------------+ | || | | Docker Engine / Containerd | | || | +-----------------------------------------------+ | || | | | || | v | || | +-----------------------------------------------+ | || | | Host OS (Linux Kernel) | | || | +-----------------------------------------------+ | || | | | || | v | || | +-----------------------------------------------+ | || | | Hardware (CPU, RAM, Disk) | | || | +-----------------------------------------------+ | || | | || | Benefits: | || | - Lightweight (share OS kernel) | || | - Fast to start (seconds) | || | - Resource efficient | || | - Portable | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Docker Architecture Components
Section titled “Docker Architecture Components” Docker Architecture Deep Dive+------------------------------------------------------------------+| || Docker Client || +-------------------------------------------------------------+ || | - CLI (docker command) | || | - REST API | || | - Communicates with Docker Daemon | || +-------------------------------------------------------------+ || | || v || Docker Daemon || +-------------------------------------------------------------+ || | - dockerd process | || | - Image management | || | - Container lifecycle | || | - Network management | || | - Volume management | || +-------------------------------------------------------------+ || | || +---------------+---------------+ || | | | || v v v || +------------+ +------------+ +------------+ || | Containerd | | runc | | Storage | || | (Container| | (Runtime) | | (GraphDB) | || | Runtime) | | | | | || +------------+ +------------+ +------------+ || || Registry || +-------------------------------------------------------------+ || | - Docker Hub | || | - Private registries | || | - Stores images | || +-------------------------------------------------------------+ || |+------------------------------------------------------------------+58.2 Docker Installation and Configuration
Section titled “58.2 Docker Installation and Configuration”Installing Docker
Section titled “Installing Docker”# =============================================================================# ARCH LINUX# =============================================================================
# Install Dockersudo pacman -S docker
# Start and enable Dockersudo systemctl enable --now docker
# Add user to docker groupsudo usermod -aG docker $USER
# Verify installationdocker --versiondocker info
# Test Dockerdocker run hello-world
# =============================================================================# UBUNTU/DEBIAN# =============================================================================
# Update packagessudo apt update
# Install dependenciessudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# Add Docker GPG keycurl -fsSL https://download.docker.com/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repositoryecho "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Dockersudo apt updatesudo apt install -y docker-ce docker-ce-cli containerd.io
# =============================================================================# RED HAT / CENTOS# =============================================================================
# Install dependenciessudo yum install -y yum-utils
# Add Docker repositorysudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# Install Dockersudo yum install -y docker-ce docker-ce-cli containerd.io
# Start Dockersudo systemctl start dockersudo systemctl enable dockerDocker Configuration
Section titled “Docker Configuration”# =============================================================================# DOCKER DAEMON CONFIGURATION# =============================================================================
# Create daemon configurationsudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<EOF{ "storage-driver": "overlay2", "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" }, "live-restore": true, "default-address-pools": [ { "base": "172.17.0.0/16", "size": 24 } ]}EOF
# Restart Dockersudo systemctl restart docker
# =============================================================================# POST-INSTALLATION SETUP# =============================================================================
# Create docker network for custom subnetdocker network create \ --driver=bridge \ --subnet=172.20.0.0/16 \ app-network
# Create persistent volumedocker volume create --name postgres-data
# List networksdocker network ls
# List volumesdocker volume ls58.3 Working with Docker Images
Section titled “58.3 Working with Docker Images”Image Concepts
Section titled “Image Concepts” Docker Image Layers+------------------------------------------------------------------+| || Image = Collection of Read-Only Layers || || +----------------------------------------------------------+ || | Container Layer (writable) | || +----------------------------------------------------------+ || | | | | | || | Layer 4 | Layer 3 | Layer 2 | Layer 1 | || | (CMD) | (RUN) | (COPY) | (FROM) | || +----------------------------------------------------------+ || || Key Points: || +----------------------------------------------------------+ || | - Each instruction creates a new layer | || | - Layers are shared between images | || | - Only changes are stored (space efficient) | || | - Copy-on-write: changes copy layer to container | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Image Commands
Section titled “Image Commands”# =============================================================================# PULLING IMAGES# =============================================================================
# Pull latest imagedocker pull nginx:latest
# Pull specific tagdocker pull nginx:1.25-alpine
# Pull all tagsdocker pull -a nginx
# Pull with digestdocker pull nginx@sha256:abc123...
# Pull from private registrydocker pull registry.example.com:5000/myimage:v1
# =============================================================================# LISTING IMAGES# =============================================================================
# List all imagesdocker imagesdocker image ls
# List dangling images (none tag)docker images -f dangling=true
# List images with filterdocker images --filter "reference=nginx:*"
# Format outputdocker images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
# =============================================================================# INSPECTING IMAGES# =============================================================================
# Show image detailsdocker image inspect nginx:latest
# Show layersdocker history nginx:latest
# Show full JSONdocker inspect nginx:latest --format='{{json .Config}}'
# =============================================================================# REMOVING IMAGES# =============================================================================
# Remove imagedocker rmi nginx:latest
# Force removedocker rmi -f nginx:latest
# Remove unused imagesdocker image prune
# Remove all unused imagesdocker image prune -a
# Remove dangling imagesdocker image prune -f
# =============================================================================# TAGGING IMAGES# =============================================================================
# Tag image for local registrydocker tag nginx:latest myregistry:5000/nginx:latest
# Tag for Docker Hubdocker tag nginx:latest username/nginx:latest
# =============================================================================# PUSHING IMAGES# =============================================================================
# Push to registrydocker push myregistry:5000/nginx:latest
# Push all tagsdocker push myregistry:5000/nginx58.4 Working with Containers
Section titled “58.4 Working with Containers”Container Lifecycle
Section titled “Container Lifecycle” Container Lifecycle+------------------------------------------------------------------+| || 1. Create (docker create) || +----------------------------------------------------------+ || | - Creates container from image | || | - Does not start container | || | - Returns container ID | || +----------------------------------------------------------+ || | || v || 2. Start (docker start) || +----------------------------------------------------------+ || | - Container begins running | || | - Executes entrypoint/cmd | || | - Container can be started/stopped multiple times | || +----------------------------------------------------------+ || | || v || 3. Run (docker run) = create + start || +----------------------------------------------------------+ || | - Creates and starts in one command | || | - Most common way to run containers | || +----------------------------------------------------------+ || | || v || 4. Stop (docker stop) || +----------------------------------------------------------+ || | - Graceful shutdown (SIGTERM, then SIGKILL) | || | - Default 10 second timeout | || +----------------------------------------------------------+ || | || v || 5. Remove (docker rm) || +----------------------------------------------------------+ || | - Only stopped containers can be removed | || | - Use -f to force remove running container | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Container Commands
Section titled “Container Commands”# =============================================================================# RUNNING CONTAINERS# =============================================================================
# Basic rundocker run nginx
# Run in detached modedocker run -d nginx
# Run with namedocker run -d --name my-nginx nginx
# Run with port mappingdocker run -d -p 8080:80 nginxdocker run -d -p 192.168.1.10:8080:80 nginx
# Run with volumedocker run -d -v /data:/var/www/html nginx
# Run with environment variablesdocker run -d -e APP_ENV=production -e DB_HOST=localhost nginx
# Run with restart policydocker run -d --restart=always nginxdocker run -d --restart=on-failure:5 nginxdocker run -d --restart=unless-stopped nginx
# Run with resource limitsdocker run -d --memory=512m --cpus=0.5 nginx
# Run interactivelydocker run -it ubuntu /bin/bashdocker run -it --rm ubuntu # Auto-remove on exit
# =============================================================================# MANAGING CONTAINERS# =============================================================================
# List running containersdocker ps
# List all containersdocker ps -a
# List with formatdocker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Start containerdocker start my-nginx
# Stop containerdocker stop my-nginxdocker stop -t 30 my-nginx # 30 second timeout
# Restart containerdocker restart my-nginx
# Pause container (freezes CPU)docker pause my-nginxdocker unpause my-nginx
# Remove containerdocker rm my-nginxdocker rm -f my-nginx # Force removedocker rm $(docker ps -aq) # Remove all
# =============================================================================# LOGS AND EXEC# =============================================================================
# View logsdocker logs my-nginxdocker logs -f my-nginx # Followdocker logs --tail 100 my-nginxdocker logs --since 1h my-nginx
# Execute command in containerdocker exec my-nginx ls -ladocker exec -it my-nginx /bin/bash
# Copy filesdocker cp my-nginx:/etc/nginx/nginx.conf ./nginx.confdocker cp ./index.html my-nginx:/usr/share/nginx/html/
# Inspect containerdocker inspect my-nginxdocker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx58.5 Docker Networking
Section titled “58.5 Docker Networking”Network Types
Section titled “Network Types” Docker Network Drivers+------------------------------------------------------------------+| || 1. Bridge (default) || +----------------------------------------------------------+ || | - Default network for containers | || | - Creates docker0 bridge (172.17.0.0/16) | || | - Containers can communicate with each other | || | - External access via port mapping | || +----------------------------------------------------------+ || || 2. Host || +----------------------------------------------------------+ || | - Container shares host's network namespace | || | - No network isolation | || | - Best performance | || +----------------------------------------------------------+ || || 3. Overlay || +----------------------------------------------------------+ || | - Multi-host networking (Docker Swarm) | || | - VXLAN encapsulation | || | - Service discovery | || +----------------------------------------------------------+ || || 4. Macvlan || +----------------------------------------------------------+ || | - Container gets MAC address | || | - Appears as physical device on network | || | - Direct network access | || +----------------------------------------------------------+ || || 5. None || +----------------------------------------------------------+ || | - Disables all networking | || | - Container is isolated | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Creating and Managing Networks
Section titled “Creating and Managing Networks”# List all networksdocker network ls# Output:# NETWORK ID NAME DRIVER SCOPE# abc123 bridge bridge local# def456 host host local# ghi789 none null local# jkl012 mynet bridge local
# Create bridge networkdocker network create -d bridge mybridge
# Create with custom subnetdocker network create \ --subnet=192.168.100.0/24 \ --gateway=192.168.100.1 \ mynetwork
# Create with specific driverdocker network create -d overlay myoverlay
# Inspect networkdocker network inspect bridge
# Connect container to networkdocker network connect mynetwork container_name
# Disconnect containerdocker network disconnect mynetwork container_name
# Remove networkdocker network rm mynetwork
# Prune unused networksdocker network pruneDNS and Service Discovery
Section titled “DNS and Service Discovery”# Containers can resolve each other by name# Docker provides embedded DNS at 127.0.0.11
# Create network with DNSdocker network create \ --internal \ --dns=8.8.8.8 \ internal-net
# Alias for service discoverydocker network connect --alias api mynetwork container_name
# Test DNS resolutiondocker run --rm --network mynetwork alpine nslookup container_namedocker run --rm --network mynetwork alpine ping -c 1 other_containerPort Mapping and Publishing
Section titled “Port Mapping and Publishing”# Basic port mapping (host:container)docker run -p 8080:80 nginx
# Listen on specific host IPdocker run -p 127.0.0.1:8080:80 nginx
# UDP portdocker run -p 8080:80/udp nginx
# Random host portdocker run -P nginx# Docker assigns random port from 32768-60999
# Port rangedocker run -p 8000-9000:80 nginx# Maps 8000-9000 to container port 80
# Multiple portsdocker run -p 8080:80 -p 8443:443 nginx
# Specific port with protocoldocker run -p 53:53/tcp -p 53:53/udp dns-container58.6 Storage Drivers and Volumes
Section titled “58.6 Storage Drivers and Volumes”Storage Driver Comparison
Section titled “Storage Driver Comparison”+------------------------------------------------------------------+| DOCKER STORAGE DRIVERS |+------------------------------------------------------------------+| || +-------------+-------------+------------------------------------+ || | Driver | Use Case | Notes | || +-------------+-------------+------------------------------------+ || | overlay2 | Production | Default, best performance | || | fuse3 | FUSE | For rootless containers | || | btrfs | Btrfs FS | Requires Btrfs filesystem | || | zfs | ZFS | Requires ZFS filesystem | || | vfs | Testing | Simple, no copy-on-write | || | devicemapper| Legacy | Deprecated in favor of overlay2 | || +-------------+-------------+------------------------------------+ || || For production: overlay2 (or fuse-overlayfs for rootless) || |+------------------------------------------------------------------+Docker Volumes
Section titled “Docker Volumes”# Create volumedocker volume create myvolume
# List volumesdocker volume ls
# Inspect volumedocker volume inspect myvolume
# Mount volume to containerdocker run -v myvolume:/data container
# Mount host directorydocker run -v /host/path:/container/path container
# Read-only mountdocker run -v myvolume:/data:ro container
# Mount with SELinux labeldocker run -v /data:/data:z containerdocker run -v /data:/data:Z container
# Create volume with specific driverdocker volume create \ --driver local \ --name mydata \ -o type=none \ -o o=bind \ -o device=/path/to/data
# Remove unused volumesdocker volume prune
# Remove specific volumedocker volume rm myvolumeBind Mounts
Section titled “Bind Mounts”# Mount config filesdocker run -v ./nginx.conf:/etc/nginx/nginx.conf:ro nginx
# Mount source code (development)docker run -v $(pwd):/app -w /app node:alpine npm start
# Mount with ro/rwdocker run -v $(pwd):/app:ro node:alpine
# tmpfs mount (memory only)docker run --tmpfs /tmp:size=100m,mode=1777 container58.7 Resource Limits
Section titled “58.7 Resource Limits”Memory Limits
Section titled “Memory Limits”# Hard memory limitdocker run -m 512m nginx
# Memory limit with reservationdocker run -m 512m --memory-reservation=256m nginx
# Memory swap limitdocker run -m 512m --memory-swap=1g nginx
# Disable swap (set to same as memory)docker run -m 512m --memory-swap=512m nginx
# Kernel memory limitdocker run -m 512m --kernel-memory=256m nginx
# OOM killer controldocker run -m 512m --oom-kill-disable nginxdocker run -m 512m --oom-score-adj=-500 nginx
# Check container statsdocker stats container_nameCPU Limits
Section titled “CPU Limits”# Limit CPU coresdocker run --cpus=1.5 nginx
# Limit to specific coresdocker run --cpuset-cpus=0,1 nginx
# Limit to specific NUMA nodedocker run --cpuset-mems=0 nginx
# CPU shares (relative weight)docker run --cpu-shares=1024 nginx
# CPU quota and perioddocker run --cpu-period=100000 --cpu-quota=50000 nginx# Same as --cpus=0.5
# Realtime CPU (requires tuning)docker run --cap-add=sys_nice --cpu-rt-runtime=950000 \ --ulimit rtprio=99 \ realtime-containerI/O Limits
Section titled “I/O Limits”# Read/Write IOPS limitsdocker run --device-read-iops=/dev/sda:1000 \ --device-write-iops=/dev/sda:1000 container
# Read/Write bandwidth limitsdocker run --device-read-bps=/dev/sda:50mb \ --device-write-bps=/dev/sda:25mb container
# Blkio weight (cgroup v1)docker run --blkio-weight=500 containerMonitoring Resources
Section titled “Monitoring Resources”# Real-time statsdocker stats
# Stats for specific containerdocker stats container_name
# JSON formatdocker stats --no-stream container_name --format "{{json .}}"
# All containersdocker stats --all
# Inspect limitsdocker inspect container_name | grep -i memorydocker inspect container_name | grep -i cpu58.8 Health Checks
Section titled “58.8 Health Checks”Defining Health Checks
Section titled “Defining Health Checks”# Dockerfile with HEALTHCHECKFROM nginx
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost/ || exit 1
# Using wget insteadHEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
# Using custom scriptHEALTHCHECK CMD /usr/local/bin/healthcheck.sh# Docker Compose health checkservices: web: image: nginx healthcheck: test: ["CMD", "curl", "-f", "http://localhost/"] interval: 30s timeout: 3s retries: 3 start_period: 10sManaging Health Checks
Section titled “Managing Health Checks”# View health statusdocker inspect --format='{{.State.Health}}' container
# Run health check manuallydocker healthcheck inspect container
# Check health status in psdocker ps -a --filter health=healthy
# Disable health check in running containerdocker update --health-cmd="none" container58.9 Multi-Stage Builds
Section titled “58.9 Multi-Stage Builds”Build Optimization
Section titled “Build Optimization”# Node.js multi-stage build# Stage 1: BuildFROM node:18-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY . .RUN npm run build
# Stage 2: ProductionFROM node:18-alpine AS productionWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesUSER nodeEXPOSE 3000CMD ["node", "dist/index.js"]# Go multi-stage buildFROM golang:1.20 AS builderWORKDIR /buildCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -o app
FROM scratchCOPY --from=builder /build/app /appEXPOSE 8080CMD ["/app"]# Python multi-stageFROM python:3.11-slim AS builderWORKDIR /buildRUN pip install --user -r requirements.txt
FROM python:3.11-slimWORKDIR /appCOPY --from=builder /root/.local /root/.localENV PATH=/root/.local/bin:$PATHCOPY . .CMD ["python", "app.py"]Build Arguments
Section titled “Build Arguments”# Using build argumentsFROM alpine AS builderARG VERSION=latestARG BUILD_DATERUN echo "Building version $VERSION on $BUILD_DATE"
FROM alpineARG VERSIONENV APP_VERSION=$VERSIONCMD ["echo", "Version: $VERSION"]# Build with argsdocker build --build-arg VERSION=1.0.0 \ --build-arg BUILD_DATE=$(date -u +%Y-%m-%d) \ -t myapp .58.10 Docker Swarm
Section titled “58.10 Docker Swarm”Initializing Swarm
Section titled “Initializing Swarm”# Initialize swarmdocker swarm init
# Get join token for workerdocker swarm join-token worker
# Get join token for managerdocker swarm join-token manager
# Join as workerdocker swarm join --token SWMTKN-1-... MANAGER_IP:2377
# Leave swarmdocker swarm leave
# Force leave (manager)docker swarm leave --forceManaging Services
Section titled “Managing Services”# Create servicedocker service create --name myservice --replicas 3 nginx
# List servicesdocker service ls
# Inspect servicedocker service inspect myservice
# Update servicedocker service update --replicas 5 myservicedocker service update --image nginx:alpine myservice
# Scale servicedocker service scale myservice=10
# Remove servicedocker service rm myserviceManaging Stacks
Section titled “Managing Stacks”# Deploy stackdocker stack deploy -c docker-compose.yml mystack
# List stacksdocker stack ls
# List services in stackdocker stack services mystack
# List tasks in stackdocker stack ps mystack
# Remove stackdocker stack rm mystack58.11 Docker Compose
Section titled “58.11 Docker Compose”Compose File Basics
Section titled “Compose File Basics”version: '3.8'
services: web: image: nginx:alpine ports: - "80:80" volumes: - ./html:/usr/share/nginx/html:ro networks: - frontend depends_on: - api restart: unless-stopped
api: build: ./api environment: - DATABASE_URL=postgres://db:5432/app networks: - frontend - backend depends_on: - db
db: image: postgres:15-alpine volumes: - db-data:/var/lib/postgresql/data networks: - backend restart: unless-stopped
networks: frontend: backend:
volumes: db-data:Compose Commands
Section titled “Compose Commands”# Start servicesdocker-compose up -d
# Start with specific filedocker-compose -f docker-compose.prod.yml up -d
# View logsdocker-compose logs -f
# List containersdocker-compose ps
# Stop servicesdocker-compose down
# Stop and remove volumesdocker-compose down -v
# Rebuild servicesdocker-compose builddocker-compose up -d --build
# Scale servicedocker-compose up -d --scale web=3
# Execute command in servicedocker-compose exec web shEnd of Chapter 58: Docker Complete Guide