Docker Cheatsheet
A comprehensive guide to Docker container technology - everything you need to know about containerization, images, containers, and orchestration
Docker Basics
Docker Architecture
Overview of Docker's client-server architecture
# Docker components
- Docker Client: Command-line tool that users interact with
- Docker Daemon: Background service that manages containers
- Docker Registry: Repository for Docker images (e.g., Docker Hub)
- Docker Objects: Images, Containers, Networks, Volumes
# Flow
1. Build an image from a Dockerfile
2. Push the image to a registry
3. Pull the image on another machine
4. Run a container from the image
Installation & Verification
Installing Docker and checking installation
# Install Docker on Ubuntu
sudo apt update
sudo apt install docker.io
# Install Docker on macOS (using Homebrew)
brew install --cask docker
# Install Docker on Windows
# Download Docker Desktop from docker.com
# Verify installation
docker --version
docker info
docker run hello-world
Docker Help
Getting help with Docker commands
# Get help on Docker CLI
docker --help
# Get help on a specific command
docker run --help
docker build --help
# Docker documentation
# https://docs.docker.com/
Working with Images
Pull Images
Downloading images from a registry
# Pull an image from Docker Hub
docker pull nginx
# Pull a specific version (tag)
docker pull node:16-alpine
# Pull from another registry
docker pull mcr.microsoft.com/dotnet/aspnet:6.0
List Images
Viewing and managing local images
# List all images
docker images
docker image ls
# Filter images
docker images --filter "dangling=true"
docker images --filter "reference=node:*"
# List images with formatted output
docker images --format "{{.ID}}: {{.Repository}}"
# Show image details
docker image inspect nginx
Building Images
Create images using a Dockerfile
# Build an image from a Dockerfile in current directory
docker build -t myapp:1.0 .
# Build with a specific Dockerfile
docker build -f Dockerfile.dev -t myapp:dev .
# Build with build arguments
docker build --build-arg ENV=production -t myapp:prod .
# Build without using cache
docker build --no-cache -t myapp:latest .
# Build multi-platform images (requires buildx)
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:multi .
Managing Images
Common image management commands
# Remove an image
docker rmi nginx
docker image rm nginx
# Remove all unused images
docker image prune
# Remove all unused images (including unused parents)
docker image prune -a
# Tag an image
docker tag myapp:latest myapp:v1.2.3
# Save an image to a tar file
docker save -o myapp.tar myapp:latest
# Load an image from a tar file
docker load -i myapp.tar
Working with Containers
Run Containers
Starting containers from images
# Run a container
docker run nginx
# Run in detached (background) mode
docker run -d nginx
# Run with a custom name
docker run --name my-nginx -d nginx
# Run with port mapping (host:container)
docker run -p 8080:80 -d nginx
# Run with environment variables
docker run -e NODE_ENV=production -d myapp
# Run with mounted volume (host:container)
docker run -v /host/path:/container/path -d nginx
# Run with bind mount (for development)
docker run -v $(pwd):/app -d myapp
# Run with memory limits
docker run --memory="512m" --memory-swap="1g" -d myapp
# Run with CPU limits
docker run --cpus="1.5" -d myapp
# Run in interactive mode with TTY
docker run -it ubuntu bash
Container Management
Managing running containers
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Stop a container
docker stop container_id
# Start a stopped container
docker start container_id
# Restart a container
docker restart container_id
# Pause a container
docker pause container_id
# Unpause a container
docker unpause container_id
# Remove a container
docker rm container_id
# Remove a running container (force)
docker rm -f container_id
# Remove all stopped containers
docker container prune
Container Operations
Working with running containers
# Execute a command in a running container
docker exec -it container_id bash
# View container logs
docker logs container_id
# Follow container logs in real-time
docker logs -f container_id
# Show container resource usage stats
docker stats container_id
# Copy files from container to host
docker cp container_id:/path/in/container /path/on/host
# Copy files from host to container
docker cp /path/on/host container_id:/path/in/container
# Inspect container details
docker inspect container_id
# View container changes
docker diff container_id
# Create a new image from a container
docker commit container_id new_image_name
Dockerfile
Dockerfile Basics
Core instructions for building Docker images
# Example Dockerfile for a Node.js application
# Set base image
FROM node:16-alpine
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy source code
COPY . .
# Build the application (if needed)
RUN npm run build
# Expose port
EXPOSE 3000
# Set environment variables
ENV NODE_ENV=production
# Command to run when container starts
CMD ["npm", "start"]
Multi-stage Builds
Create smaller images with build and runtime stages
# Example multi-stage build for a Node.js app
# Build stage
FROM node:16-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM node:16-alpine
WORKDIR /app
COPY --from=build /app/package*.json ./
COPY --from=build /app/dist ./dist
# Only install production dependencies
RUN npm install --only=production
EXPOSE 3000
CMD ["node", "dist/main.js"]
Dockerfile Best Practices
Recommended practices for efficient Dockerfiles
# 1. Use specific image tags instead of 'latest'
FROM node:16.15.1-alpine3.16
# 2. Group RUN commands to reduce layers
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 3. Use .dockerignore file to exclude files
# Example .dockerignore:
# node_modules
# npm-debug.log
# .git
# .env
# 4. Place instructions that change less frequently at the top
COPY package.json .
RUN npm install
# Source code changes often, so copy it later
COPY . .
# 5. Use non-root user for security
RUN addgroup -g 1001 -S appuser && \
adduser -u 1001 -S appuser -G appuser
USER appuser
# 6. Use ENTRYPOINT with CMD for more flexibility
ENTRYPOINT ["node"]
CMD ["index.js"]
# 7. Set proper health checks
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
Docker Compose
Docker Compose Basics
Define and run multi-container applications
# docker-compose.yml example
version: '3.8'
services:
web:
build: ./web
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/app
depends_on:
- db
db:
image: postgres:14
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=postgres
- POSTGRES_DB=app
volumes:
postgres_data:
Docker Compose Commands
Common commands for Docker Compose
# Start services defined in docker-compose.yml
docker-compose up
# Start in detached mode
docker-compose up -d
# Stop services
docker-compose down
# Stop services and remove volumes
docker-compose down -v
# View logs
docker-compose logs
# Follow logs
docker-compose logs -f
# View logs for specific service
docker-compose logs web
# Build or rebuild services
docker-compose build
# Restart services
docker-compose restart
# Show running services
docker-compose ps
# Run a command in a service
docker-compose exec web npm test
# Scale a service (start multiple containers)
docker-compose up -d --scale web=3
Docker Compose Features
Advanced Docker Compose configuration
# Advanced docker-compose.yml
version: '3.8'
services:
web:
build:
context: ./web
dockerfile: Dockerfile.dev
ports:
- "8000:8000"
volumes:
- ./web:/app
- /app/node_modules
environment:
- NODE_ENV=development
deploy:
replicas: 2
resources:
limits:
cpus: '0.5'
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
restart: unless-stopped
networks:
- frontend
- backend
db:
image: postgres:14
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
networks:
- backend
networks:
frontend:
backend:
volumes:
postgres_data:
secrets:
db_password:
file: ./db_password.txt
Docker Networking
Network Basics
Docker network types and commands
# List networks
docker network ls
# Docker network types:
# - bridge: Default network for containers (internal network)
# - host: Container uses host's network (no isolation)
# - none: No networking
# - overlay: Multi-host networking (for Swarm)
# - macvlan: Assign MAC address to container (appears as physical device)
# Create a network
docker network create mynetwork
# Create a network with specific subnet
docker network create --subnet=172.18.0.0/16 mynetwork
# Inspect a network
docker network inspect mynetwork
# Remove a network
docker network rm mynetwork
# Remove all unused networks
docker network prune
Container Networking
Connect containers to networks
# Start a container on a specific network
docker run --network=mynetwork --name=container1 -d nginx
# Connect a running container to a network
docker network connect mynetwork container2
# Disconnect a container from a network
docker network disconnect mynetwork container2
# Run with DNS settings
docker run --dns=8.8.8.8 --dns-search=example.com -d nginx
# Run with a hostname
docker run --hostname=webserver -d nginx
# Add a host entry to container
docker run --add-host=database:192.168.1.10 -d nginx
Container Communication
How containers communicate with each other
# Example: 3-tier application networking
# 1. Create a network
docker network create app-network
# 2. Start a database (backend tier)
docker run --name db --network=app-network -d postgres
# 3. Start an API server (middle tier)
docker run --name api \
--network=app-network \
-e DB_HOST=db \
-d myapi
# 4. Start a web server (frontend tier)
docker run --name web \
--network=app-network \
-e API_URL=http://api:3000 \
-p 80:80 \
-d nginx
# Containers on the same network can reach each other by name
# "web" can reach "api" at http://api:3000
# "api" can reach "db" at db:5432
# Only "web" is accessible from the host at localhost:80
Docker Volumes
Volume Types
Different ways to persist data in Docker
# Three types of volumes:
# 1. Named volumes (managed by Docker)
docker run -v mydata:/app/data -d myapp
# 2. Bind mounts (host directory mounted into container)
docker run -v /host/path:/container/path -d myapp
# 3. tmpfs mounts (stored in host memory, not disk)
docker run --tmpfs /app/temp -d myapp
# New syntax (recommended)
# Named volume
docker run --mount source=mydata,target=/app/data -d myapp
# Bind mount
docker run --mount type=bind,source=/host/path,target=/container/path -d myapp
# tmpfs mount
docker run --mount type=tmpfs,target=/app/temp -d myapp
Working with Volumes
Managing Docker volumes
# Create a volume
docker volume create mydata
# List volumes
docker volume ls
# Inspect a volume
docker volume inspect mydata
# Remove a volume
docker volume rm mydata
# Remove all unused volumes
docker volume prune
# Backup a volume
docker run --rm -v mydata:/source -v $(pwd):/backup alpine \
tar -czvf /backup/mydata.tar.gz -C /source .
# Restore a volume
docker run --rm -v mydata:/target -v $(pwd):/backup alpine \
tar -xzvf /backup/mydata.tar.gz -C /target
Volume Use Cases
Common scenarios for using Docker volumes
# Database data persistence
docker run -v postgres_data:/var/lib/postgresql/data -d postgres
# Configuration files
docker run -v ./config.json:/app/config.json:ro -d myapp
# Shared data between containers
docker run -v shared_data:/shared -d serviceA
docker run -v shared_data:/shared -d serviceB
# Development environments (hot reload)
docker run -v $(pwd):/app -d myapp
# Logs persistence
docker run -v ./logs:/var/log/nginx -d nginx
# Caching build dependencies
docker run -v node_modules:/app/node_modules -v $(pwd):/app -d node
Docker Registry & Hub
Docker Hub Basics
Using Docker's public registry
# Log in to Docker Hub
docker login
# Search for images
docker search nginx
# Pull an image from Docker Hub
docker pull nginx:latest
# Tag an image for Docker Hub (username/repo:tag)
docker tag myapp:latest username/myapp:1.0
# Push an image to Docker Hub
docker push username/myapp:1.0
# Log out from Docker Hub
docker logout
Private Registries
Working with private Docker registries
# Log in to a private registry
docker login registry.example.com
# Pull from private registry
docker pull registry.example.com/myteam/myapp:latest
# Tag for private registry
docker tag myapp:latest registry.example.com/myteam/myapp:1.0
# Push to private registry
docker push registry.example.com/myteam/myapp:1.0
# Using AWS ECR
aws ecr get-login-password | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com
# Using Azure Container Registry
az acr login --name myregistry
Running a Local Registry
Set up a local Docker registry for testing
# Run a local registry container
docker run -d -p 5000:5000 --name registry registry:2
# Tag an image for local registry
docker tag myapp:latest localhost:5000/myapp:latest
# Push to local registry
docker push localhost:5000/myapp:latest
# Pull from local registry
docker pull localhost:5000/myapp:latest
# Add insecure registry to Docker daemon (for non-TLS registries)
# Edit /etc/docker/daemon.json:
{
"insecure-registries": ["localhost:5000"]
}
# Restart Docker daemon
sudo systemctl restart docker
Docker Swarm
Swarm Basics
Docker's native orchestration solution
# Initialize a swarm
docker swarm init --advertise-addr 192.168.1.10
# View join token for workers
docker swarm join-token worker
# View join token for managers
docker swarm join-token manager
# Join a swarm as a worker
docker swarm join --token <token> 192.168.1.10:2377
# List nodes in swarm
docker node ls
# Promote worker to manager
docker node promote worker1
# Demote manager to worker
docker node demote manager2
# Leave a swarm
docker swarm leave
# Force leave (for managers)
docker swarm leave --force
Services & Stacks
Deploy applications in Swarm mode
# Create a service
docker service create --name web --replicas 3 -p 80:80 nginx
# List services
docker service ls
# Inspect a service
docker service inspect web
# View service logs
docker service logs web
# Scale a service
docker service scale web=5
# Update a service
docker service update --image nginx:alpine web
# Remove a service
docker service rm web
# Deploy a stack from a compose file
docker stack deploy -c docker-compose.yml mystack
# List stacks
docker stack ls
# List services in a stack
docker stack services mystack
# Remove a stack
docker stack rm mystack
Docker Security
Security Best Practices
Recommendations for securing Docker deployments
# 1. Keep Docker updated
docker version
# 2. Use official or verified images
docker pull nginx
# 3. Scan images for vulnerabilities
docker scan myapp:latest
# 4. Run containers with limited capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# 5. Use read-only file systems where possible
docker run --read-only nginx
# 6. Set resource limits
docker run --memory="512m" --cpus="0.5" nginx
# 7. Don't run containers as root
# In Dockerfile:
USER 1000
# 8. Use secrets management
docker run --secret=db_password nginx
# 9. Use security options
docker run --security-opt=no-new-privileges nginx
# 10. Use network isolation
docker network create --internal private_network
Container Isolation
Techniques for isolating containers
# Run with custom namespace (user)
docker run --userns=host nginx
# Use security profiles (AppArmor)
docker run --security-opt apparmor=my_profile nginx
# Use security profiles (Seccomp)
docker run --security-opt seccomp=seccomp-profile.json nginx
# No new privileges flag
docker run --security-opt=no-new-privileges nginx
# Use read-only root filesystem
docker run --read-only nginx
# Set a custom PID mode
docker run --pid=host nginx
# Set a custom IPC mode
docker run --ipc=host nginx
Docker Bench Security
Tool for auditing Docker security
# Run Docker Bench Security (official Docker security scanning tool)
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /etc/docker:/etc/docker \
-v /etc:/host/etc \
docker/docker-bench-security
# Typical security issues to address:
# - Docker daemon configuration
# - File permissions
# - Container runtime
# - Docker security operations
# - Docker swarm configuration
# - Container images management
# - Container runtime
# Run Trivy for image vulnerability scanning
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image nginx:latest
Docker Performance
Performance Monitoring
Tools and commands to monitor Docker performance
# View container resource usage
docker stats
# Format stats output
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# Monitor specific containers
docker stats container1 container2
# Top processes in a container
docker top container_id
# System-wide information
docker system df
# Detailed system information
docker info
# Third-party tools
# - cAdvisor: Container resource usage metrics
# - Prometheus: Metrics collection and alerting
# - Grafana: Metrics visualization
# - Datadog: Container monitoring service
# - Elasticsearch + Fluentd + Kibana (EFK): Logging stack
Resource Constraints
Limiting container resource usage
# Memory constraints
docker run --memory="512m" --memory-reservation="256m" nginx
# CPU constraints
docker run --cpus="1.5" --cpu-shares=1024 nginx
# Block I/O constraints
docker run --blkio-weight=600 nginx
# Pids limit (limit number of processes)
docker run --pids-limit=100 nginx
# Restart policies
docker run --restart=on-failure:5 nginx
docker run --restart=always nginx
docker run --restart=unless-stopped nginx
# Set ulimits
docker run --ulimit nofile=1024:2048 nginx
Performance Best Practices
Tips for optimizing Docker performance
# 1. Use lightweight base images
FROM alpine:3.16
FROM node:16-alpine
# 2. Optimize layers
# Combine RUN commands
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean
# 3. Multi-stage builds to reduce image size
FROM node:16 AS build
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM node:16-alpine
COPY --from=build /app/dist /app/dist
CMD ["node", "/app/dist/main.js"]
# 4. Remove unnecessary files
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 5. Use .dockerignore file
# node_modules
# .git
# test
# coverage
# 6. Tune Docker daemon (daemon.json)
{
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}