Docker

Quick Reference

# Container lifecycle
docker run -d --name web -p 8080:80 nginx
docker ps -a
docker stop web
docker start web
docker rm web

# Images
docker images
docker pull alpine:latest
docker build -t myapp:1.0 .
docker push registry.example.com/myapp:1.0

# Exec and logs
docker exec -it web /bin/sh
docker logs -f web

# Cleanup
docker system prune -af

Installation

Arch Linux

# Install Docker
sudo pacman -S docker docker-compose docker-buildx

# Enable and start
sudo systemctl enable --now docker.service

# Add user to docker group (logout required)
sudo usermod -aG docker $USER

Debian/Ubuntu

# Add Docker repository
sudo apt update
sudo apt install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
    https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list

# Install
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Add user to docker group
sudo usermod -aG docker $USER

RHEL/CentOS/Fedora

# Add repository
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo

# Install
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Enable and start
sudo systemctl enable --now docker

# Add user to docker group
sudo usermod -aG docker $USER

Container Management

Run Containers

# Basic run
docker run nginx

# Detached with name
docker run -d --name webserver nginx

# Interactive with TTY
docker run -it alpine /bin/sh

# With port mapping
docker run -d -p 8080:80 nginx             # Host:Container
docker run -d -p 127.0.0.1:8080:80 nginx   # Bind to localhost only

# With volume mount
docker run -d -v /host/path:/container/path nginx
docker run -d -v myvolume:/data nginx       # Named volume

# With environment variables
docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql

# With resource limits
docker run -d --memory=512m --cpus=1.5 nginx

# Auto-remove when stopped
docker run --rm alpine echo "Hello"

# With restart policy
docker run -d --restart=unless-stopped nginx
docker run -d --restart=always nginx

List and Inspect

# List running containers
docker ps

# List all containers
docker ps -a

# List with formatting
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"

# Inspect container
docker inspect webserver
docker inspect --format '{{.NetworkSettings.IPAddress}}' webserver

# Container stats
docker stats
docker stats webserver

# Container logs
docker logs webserver
docker logs -f webserver          # Follow
docker logs --tail 100 webserver  # Last 100 lines
docker logs --since 1h webserver  # Last hour

Container Lifecycle

# Stop container
docker stop webserver
docker stop -t 30 webserver   # 30 second timeout

# Start stopped container
docker start webserver

# Restart
docker restart webserver

# Pause/unpause
docker pause webserver
docker unpause webserver

# Kill (force stop)
docker kill webserver

# Remove container
docker rm webserver
docker rm -f webserver        # Force remove running
docker rm -v webserver        # Also remove volumes

# Remove all stopped containers
docker container prune

Execute Commands

# Execute command in running container
docker exec webserver ls /etc/nginx

# Interactive shell
docker exec -it webserver /bin/bash
docker exec -it webserver /bin/sh

# As specific user
docker exec -u root webserver whoami

# With environment variable
docker exec -e MY_VAR=value webserver env

# Working directory
docker exec -w /app webserver pwd

Copy Files

# Copy from container to host
docker cp webserver:/etc/nginx/nginx.conf ./nginx.conf

# Copy from host to container
docker cp ./config.txt webserver:/app/config.txt

# Copy directory
docker cp webserver:/var/log ./logs/

Image Management

Pull and List

# Pull image
docker pull nginx
docker pull nginx:1.25
docker pull nginx:alpine

# List images
docker images
docker images -a              # Include intermediate

# Search Docker Hub
docker search nginx

# Image history
docker history nginx

# Inspect image
docker inspect nginx

Build Images

# Build from Dockerfile
docker build -t myapp:1.0 .
docker build -t myapp:1.0 -f Dockerfile.prod .

# Build with build args
docker build --build-arg VERSION=1.0 -t myapp .

# Build without cache
docker build --no-cache -t myapp .

# Multi-platform build (with buildx)
docker buildx build --platform linux/amd64,linux/arm64 -t myapp .

# Tag image
docker tag myapp:1.0 registry.example.com/myapp:1.0
docker tag myapp:1.0 myapp:latest

# Push to registry
docker push registry.example.com/myapp:1.0

Dockerfile Best Practices

# Use specific base image version
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Copy dependencies first (better caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Create non-root user
RUN useradd -m -r appuser && chown -R appuser:appuser /app
USER appuser

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:8000/health || exit 1

# Start command
CMD ["python", "app.py"]

Image Cleanup

# Remove image
docker rmi nginx
docker rmi -f nginx           # Force

# Remove unused images
docker image prune
docker image prune -a         # Remove all unused

# Remove dangling images
docker images -f "dangling=true" -q | xargs docker rmi

Volumes

Volume Management

# Create volume
docker volume create mydata

# List volumes
docker volume ls

# Inspect volume
docker volume inspect mydata

# Remove volume
docker volume rm mydata

# Remove unused volumes
docker volume prune

Using Volumes

# Named volume
docker run -d -v mydata:/app/data nginx

# Bind mount (host path)
docker run -d -v /host/path:/container/path nginx

# Read-only mount
docker run -d -v /host/path:/container/path:ro nginx

# tmpfs mount (memory)
docker run -d --tmpfs /tmp nginx

# Mount with options
docker run -d --mount type=volume,source=mydata,target=/app/data nginx
docker run -d --mount type=bind,source=/host/path,target=/app nginx

Backup and Restore

# Backup volume to tar
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
    tar czf /backup/mydata.tar.gz -C /data .

# Restore from tar
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
    tar xzf /backup/mydata.tar.gz -C /data

Networking

Network Basics

# List networks
docker network ls

# Inspect network
docker network inspect bridge

# Create network
docker network create mynetwork
docker network create --driver bridge mynetwork
docker network create --subnet=172.20.0.0/16 mynetwork

# Remove network
docker network rm mynetwork

# Prune unused networks
docker network prune

Container Networking

# Connect container to network
docker network connect mynetwork webserver

# Disconnect from network
docker network disconnect mynetwork webserver

# Run with specific network
docker run -d --network mynetwork --name web nginx

# Run with hostname
docker run -d --network mynetwork --hostname webhost nginx

# Run with static IP
docker run -d --network mynetwork --ip 172.20.0.10 nginx

# Run with host networking
docker run -d --network host nginx

# Run with no networking
docker run -d --network none nginx

DNS and Service Discovery

# Containers on same user-defined network can resolve by name
docker network create app-network
docker run -d --network app-network --name db postgres
docker run -d --network app-network --name web myapp

# From web container, 'db' hostname resolves to postgres container

# Custom DNS
docker run -d --dns 8.8.8.8 nginx

# Custom /etc/hosts entry
docker run -d --add-host db:192.168.1.100 nginx

Docker Compose

Basic Compose File

# compose.yaml (or docker-compose.yml)
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      - api
    networks:
      - frontend

  api:
    build: ./api
    environment:
      - DATABASE_URL=postgres://db:5432/app
    networks:
      - frontend
      - backend

  db:
    image: postgres:15
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    networks:
      - backend

volumes:
  db-data:

networks:
  frontend:
  backend:

secrets:
  db_password:
    file: ./secrets/db_password.txt

Compose Commands

# Start services
docker compose up
docker compose up -d              # Detached
docker compose up --build         # Rebuild images

# Stop services
docker compose down
docker compose down -v            # Also remove volumes
docker compose down --rmi all     # Also remove images

# Service management
docker compose start
docker compose stop
docker compose restart

# View logs
docker compose logs
docker compose logs -f web        # Follow specific service

# Execute in service
docker compose exec web /bin/sh

# Scale services
docker compose up -d --scale web=3

# List services
docker compose ps

# Pull latest images
docker compose pull

# Build images
docker compose build
docker compose build --no-cache

Environment and Profiles

# compose.yaml with profiles
services:
  web:
    image: nginx

  debug:
    image: alpine
    profiles:
      - debug
    command: tail -f /dev/null

  test:
    build: ./test
    profiles:
      - test
# Use profiles
docker compose --profile debug up
docker compose --profile test up

# Environment file
docker compose --env-file .env.prod up

Security

User Namespaces

# Run as specific user
docker run -u 1000:1000 nginx

# Run as non-root (if image supports)
docker run --user nobody nginx

# Read-only root filesystem
docker run --read-only nginx

# Drop capabilities
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx

# No new privileges
docker run --security-opt no-new-privileges nginx

Resource Limits

# Memory limits
docker run -m 512m nginx                    # Hard limit
docker run -m 512m --memory-swap 1g nginx   # With swap

# CPU limits
docker run --cpus 1.5 nginx                 # 1.5 cores
docker run --cpu-shares 512 nginx           # Relative weight
docker run --cpuset-cpus 0,1 nginx          # Specific CPUs

# PIDs limit
docker run --pids-limit 100 nginx

# Ulimits
docker run --ulimit nofile=1024:2048 nginx

Secrets Management

# Using environment variables (less secure)
docker run -e DB_PASSWORD=secret myapp

# Using files
docker run -v /secrets/db_pass:/run/secrets/db_pass:ro myapp

# Docker Compose secrets
# secrets:
#   db_password:
#     file: ./db_password.txt

Registry Operations

Docker Hub

# Login
docker login

# Logout
docker logout

# Pull from Docker Hub
docker pull nginx
docker pull library/nginx:1.25

# Push to Docker Hub
docker tag myapp:1.0 username/myapp:1.0
docker push username/myapp:1.0

Private Registry

# Login to private registry
docker login registry.example.com

# Pull from private registry
docker pull registry.example.com/myapp:1.0

# Push to private registry
docker tag myapp:1.0 registry.example.com/myapp:1.0
docker push registry.example.com/myapp:1.0

# Run local registry
docker run -d -p 5000:5000 --name registry registry:2

# Push to local registry
docker tag myapp:1.0 localhost:5000/myapp:1.0
docker push localhost:5000/myapp:1.0

Daemon Configuration

daemon.json

# /etc/docker/daemon.json
{
  "data-root": "/var/lib/docker",
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-address-pools": [
    {"base": "172.17.0.0/16", "size": 24}
  ],
  "insecure-registries": ["registry.internal:5000"],
  "registry-mirrors": ["https://mirror.example.com"],
  "live-restore": true,
  "userland-proxy": false
}
# Apply changes
sudo systemctl restart docker

# Verify configuration
docker info

Logging Configuration

# View daemon logs
journalctl -u docker.service

# Container logging drivers
docker run -d --log-driver json-file --log-opt max-size=10m nginx
docker run -d --log-driver syslog nginx
docker run -d --log-driver journald nginx
docker run -d --log-driver none nginx    # Disable logging

Troubleshooting

Common Issues

# Permission denied
sudo usermod -aG docker $USER
# Then logout and login

# Cannot connect to Docker daemon
sudo systemctl start docker
sudo systemctl status docker

# Disk space issues
docker system df
docker system prune -af

# Container won't start - check logs
docker logs container_name
docker inspect container_name

# Network issues
docker network inspect bridge
docker exec container_name ping other_container

Debug Commands

# Docker system information
docker info
docker version

# Container processes
docker top container_name

# Real-time events
docker events

# Resource usage
docker stats

# Diff (changed files)
docker diff container_name

# Export container filesystem
docker export container_name > container.tar

# Container low-level info
docker inspect container_name | jq '.[0].State'
docker inspect container_name | jq '.[0].NetworkSettings'

System Cleanup

# Show disk usage
docker system df
docker system df -v

# Remove all unused data
docker system prune

# Remove everything (including images)
docker system prune -af

# Remove specific resources
docker container prune    # Stopped containers
docker image prune -a     # Unused images
docker volume prune       # Unused volumes
docker network prune      # Unused networks

# Remove old images
docker images --filter "dangling=true" -q | xargs docker rmi

Quick Command Reference

# Containers
docker run -d --name NAME IMAGE                    # Run detached
docker ps -a                                       # List all
docker stop NAME                                   # Stop
docker rm NAME                                     # Remove
docker exec -it NAME /bin/sh                       # Shell access
docker logs -f NAME                                # Follow logs

# Images
docker pull IMAGE:TAG                              # Download
docker build -t NAME:TAG .                         # Build
docker push REGISTRY/NAME:TAG                      # Upload
docker rmi IMAGE                                   # Remove

# Volumes
docker volume create NAME                          # Create
docker volume ls                                   # List
docker volume rm NAME                              # Remove

# Networks
docker network create NAME                         # Create
docker network connect NAME CONTAINER              # Attach

# Compose
docker compose up -d                               # Start
docker compose down                                # Stop
docker compose logs -f                             # Logs

# Cleanup
docker system prune -af                            # Remove all unused