The Complete Docker Guide: From Installation to Production - Commands & Best Practices
A comprehensive guide covering Docker from scratch - installation, containers, images, volumes, networks, Docker Compose, and production best practices. Master Docker with detailed examples and complete command reference.
Whether you're just starting with containerization or need a comprehensive Docker reference, this guide covers everything from installation to production deployments. Learn Docker concepts, master essential commands, and understand best practices for building and deploying containerized applications.
Table of Contents
- What is Docker?
- Docker Installation
- Docker Architecture & Concepts
- Working with Docker Images
- Working with Docker Containers
- Docker Volumes - Data Persistence
- Docker Networks
- Creating Docker Images - Dockerfile
- Docker Compose
- Docker Registry & Hub
- Docker Best Practices
- Monitoring & Logging
- Troubleshooting
- Security Best Practices
- Quick Reference Card
What is Docker?
Introduction to Docker
Docker is a platform for developing, shipping, and running applications in containers. Containers package your application with all its dependencies, ensuring it runs consistently across different environments.
Key Benefits:
- Consistency - "Works on my machine" is now "Works everywhere"
- Isolation - Applications run in isolated environments
- Efficiency - Lightweight compared to virtual machines
- Portability - Run anywhere Docker is installed
- Scalability - Easy to scale up or down
- Version Control - Images are versioned and reproducible
Docker vs Virtual Machines
| Feature | Docker Container | Virtual Machine |
|---|---|---|
| Size | Megabytes | Gigabytes |
| Startup Time | Seconds | Minutes |
| Performance | Near-native | Overhead from hypervisor |
| Isolation | Process-level | Complete OS isolation |
| Resource Usage | Shared kernel | Separate OS per VM |
| Portability | Highly portable | Less portable |
Core Docker Concepts
Image:
- Read-only template with application code and dependencies
- Built from a Dockerfile
- Stored in registries (Docker Hub, private registries)
- Versioned using tags
Container:
- Running instance of an image
- Isolated process with its own filesystem
- Can be started, stopped, moved, and deleted
- Ephemeral by default (data lost when deleted)
Dockerfile:
- Text file with instructions to build an image
- Defines base image, dependencies, and configuration
- Reproducible and version-controlled
Registry:
- Storage and distribution system for Docker images
- Docker Hub is the default public registry
- Can host private registries
Volume:
- Persistent data storage
- Survives container deletion
- Shared between containers
Network:
- Enables container communication
- Isolates container networking
- Multiple network drivers available
Docker Installation
Installing Docker on Linux (Ubuntu/Debian)
Step 1: Update System and Install Prerequisites
Bash10 lines1# Update package index 2sudo apt update 3 4# Install required packages 5sudo apt install -y \ 6 apt-transport-https \ 7 ca-certificates \ 8 curl \ 9 gnupg \ 10 lsb-release
Step 2: Add Docker's Official GPG Key
Bash6 lines1# Create directory for keyrings 2sudo mkdir -p /etc/apt/keyrings 3 4# Add Docker's official GPG key 5curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \ 6 sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Step 3: Set Up Docker Repository
Bash6 lines1# Add Docker repository 2echo \ 3 "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ 4 https://download.docker.com/linux/ubuntu \ 5 $(lsb_release -cs) stable" | \ 6 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Step 4: Install Docker Engine
Bash5 lines1# Update package index again 2sudo apt update 3 4# Install Docker Engine, CLI, and containerd 5sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Step 5: Verify Installation
Bash8 lines1# Check Docker version 2docker --version 3 4# Check Docker Compose version 5docker compose version 6 7# Run test container 8sudo docker run hello-world
Post-Installation Steps
Add Your User to Docker Group (Avoid sudo)
Bash11 lines1# Create docker group (usually exists) 2sudo groupadd docker 3 4# Add your user to docker group 5sudo usermod -aG docker $USER 6 7# Apply group changes (or log out and back in) 8newgrp docker 9 10# Verify you can run docker without sudo 11docker run hello-world
Enable Docker to Start on Boot
Bash6 lines1# Enable Docker service 2sudo systemctl enable docker.service 3sudo systemctl enable containerd.service 4 5# Check status 6sudo systemctl status docker
Installing Docker on Other Systems
CentOS/RHEL/Fedora
Bash19 lines1# Remove old versions 2sudo yum remove docker docker-client docker-client-latest \ 3 docker-common docker-latest docker-latest-logrotate \ 4 docker-logrotate docker-engine 5 6# Install dependencies 7sudo yum install -y yum-utils 8 9# Add Docker repository 10sudo yum-config-manager --add-repo \ 11 https://download.docker.com/linux/centos/docker-ce.repo 12 13# Install Docker 14sudo yum install -y docker-ce docker-ce-cli containerd.io \ 15 docker-buildx-plugin docker-compose-plugin 16 17# Start Docker 18sudo systemctl start docker 19sudo systemctl enable docker
macOS
Bash5 lines1# Download Docker Desktop from: 2# https://www.docker.com/products/docker-desktop 3 4# Or using Homebrew: 5brew install --cask docker
Windows
Bash5 lines1# Download Docker Desktop from: 2# https://www.docker.com/products/docker-desktop 3 4# Requires WSL 2 (Windows Subsystem for Linux) 5# Enable WSL 2 feature in Windows
Verify Docker Installation
Bash14 lines1# Check Docker version 2docker version 3 4# Check detailed information 5docker info 6 7# Run test container 8docker run hello-world 9 10# Check running containers 11docker ps 12 13# Check all containers (including stopped) 14docker ps -a
Docker Architecture & Concepts
Docker Architecture Overview
CODE19 lines1┌─────────────────────────────────────────────┐ 2│ Docker Client (docker CLI) │ 3└──────────────────┬──────────────────────────┘ 4 │ REST API 5┌──────────────────▼──────────────────────────┐ 6│ Docker Daemon (dockerd) │ 7│ ┌────────────────────────────────────────┐ │ 8│ │ Container Runtime │ │ 9│ │ ┌──────────┐ ┌──────────┐ │ │ 10│ │ │Container1│ │Container2│ ... │ │ 11│ │ └──────────┘ └──────────┘ │ │ 12│ └────────────────────────────────────────┘ │ 13│ ┌────────────────────────────────────────┐ │ 14│ │ Image Storage │ │ 15│ └────────────────────────────────────────┘ │ 16│ ┌────────────────────────────────────────┐ │ 17│ │ Volume Storage │ │ 18│ └────────────────────────────────────────┘ │ 19└─────────────────────────────────────────────┘
Docker Components
Docker Client:
- Command-line tool (docker CLI)
- Sends commands to Docker daemon
- Can connect to remote daemons
Docker Daemon (dockerd):
- Background service that manages Docker objects
- Listens for Docker API requests
- Manages images, containers, networks, and volumes
Docker Registry:
- Stores Docker images
- Docker Hub is the default public registry
- Can run private registries
containerd:
- Industry-standard container runtime
- Manages container lifecycle
- Used by Docker and Kubernetes
Docker Object Hierarchy
CODE17 lines1Registry (Docker Hub) 2 │ 3 ├── Repository (nginx) 4 │ ├── Image (nginx:latest) 5 │ ├── Image (nginx:1.21) 6 │ └── Image (nginx:alpine) 7 │ 8 └── Repository (myapp) 9 ├── Image (myapp:v1.0) 10 └── Image (myapp:v2.0) 11 12Image (nginx:latest) 13 │ 14 └── Container (running instance) 15 ├── Network (bridge) 16 ├── Volume (data) 17 └── Environment variables
Working with Docker Images
Understanding Docker Images
What is a Docker Image?
- Read-only template containing application code, libraries, and dependencies
- Built in layers (each instruction in Dockerfile creates a layer)
- Layers are cached and reusable
- Images are immutable - changes create new layers
Searching for Images
Bash8 lines1# Search Docker Hub for images 2docker search nginx 3 4# Search with filters 5docker search --filter stars=100 nginx 6 7# Limit results 8docker search --limit 5 nginx
Pulling Images from Registry
Bash11 lines1# Pull latest version 2docker pull nginx 3 4# Pull specific version (tag) 5docker pull nginx:1.21 6 7# Pull from specific registry 8docker pull gcr.io/google-containers/nginx 9 10# Pull all tags of an image 11docker pull -a nginx
Listing Images
Bash17 lines1# List all images 2docker images 3 4# List with full information 5docker images --all 6 7# List image IDs only 8docker images -q 9 10# List images with specific name 11docker images nginx 12 13# List dangling images (untagged) 14docker images -f dangling=true 15 16# Format output 17docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
Inspecting Images
Bash11 lines1# View detailed information about an image 2docker inspect nginx 3 4# View image history (layers) 5docker history nginx 6 7# View specific information using format 8docker inspect --format='{{.Config.Env}}' nginx 9 10# Check image size 11docker images nginx --format "{{.Size}}"
Tagging Images
Bash9 lines1# Tag an image 2docker tag nginx:latest myregistry/nginx:v1.0 3 4# Tag with multiple tags 5docker tag nginx:latest mynginx:latest 6docker tag nginx:latest mynginx:stable 7 8# View all tags 9docker images mynginx
Removing Images
Bash20 lines1# Remove image by name 2docker rmi nginx 3 4# Remove image by ID 5docker rmi abc123def456 6 7# Remove multiple images 8docker rmi nginx redis mysql 9 10# Force remove (even if containers exist) 11docker rmi -f nginx 12 13# Remove all unused images 14docker image prune 15 16# Remove all images 17docker rmi $(docker images -q) 18 19# Remove dangling images only 20docker image prune -a --filter "dangling=true"
Saving and Loading Images
Bash16 lines1# Save image to tar file 2docker save nginx > nginx.tar 3docker save -o nginx.tar nginx 4 5# Save multiple images 6docker save -o images.tar nginx redis mysql 7 8# Load image from tar file 9docker load < nginx.tar 10docker load -i nginx.tar 11 12# Export container to tar (includes changes) 13docker export container_name > container.tar 14 15# Import from tar as new image 16docker import container.tar myimage:latest
Image Size Management
Bash14 lines1# View image sizes 2docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 3 4# View disk usage 5docker system df 6 7# Detailed disk usage 8docker system df -v 9 10# Clean up unused images 11docker image prune -a 12 13# Remove images older than 24 hours 14docker image prune -a --filter "until=24h"
Working with Docker Containers
Container Lifecycle
CODE3 lines1Created → Running → Paused → Stopped → Removed 2 ↓ ↓ ↓ ↓ 3 start pause unpause restart
Running Containers
Basic Container Operations
Bash32 lines1# Run a container (creates and starts) 2docker run nginx 3 4# Run container in background (detached mode) 5docker run -d nginx 6 7# Run with a custom name 8docker run --name my-nginx nginx 9 10# Run and remove when stopped 11docker run --rm nginx 12 13# Run interactively with terminal 14docker run -it ubuntu bash 15 16# Run with port mapping 17docker run -p 8080:80 nginx 18 19# Run with environment variables 20docker run -e "ENV=production" nginx 21 22# Run with volume mount 23docker run -v /host/path:/container/path nginx 24 25# Complete example with multiple options 26docker run -d \ 27 --name my-app \ 28 -p 8080:80 \ 29 -e "NODE_ENV=production" \ 30 -v /data:/app/data \ 31 --restart unless-stopped \ 32 nginx:latest
Advanced Run Options
Bash29 lines1# Limit CPU usage (50%) 2docker run --cpus=0.5 nginx 3 4# Limit memory (512 MB) 5docker run -m 512m nginx 6 7# Set working directory 8docker run -w /app nginx 9 10# Run with specific user 11docker run -u 1000:1000 nginx 12 13# Set hostname 14docker run --hostname myapp nginx 15 16# Add to network 17docker run --network my-network nginx 18 19# Mount tmpfs (temporary filesystem) 20docker run --tmpfs /tmp nginx 21 22# Read-only root filesystem 23docker run --read-only nginx 24 25# Add capabilities 26docker run --cap-add=NET_ADMIN nginx 27 28# Set restart policy 29docker run --restart always nginx
Container Management Commands
Bash44 lines1# List running containers 2docker ps 3 4# List all containers (including stopped) 5docker ps -a 6 7# List container IDs only 8docker ps -q 9 10# List with specific format 11docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" 12 13# Start stopped container 14docker start container_name 15 16# Stop running container 17docker stop container_name 18 19# Stop with timeout 20docker stop -t 30 container_name 21 22# Restart container 23docker restart container_name 24 25# Pause container 26docker pause container_name 27 28# Unpause container 29docker unpause container_name 30 31# Kill container (force stop) 32docker kill container_name 33 34# Remove container 35docker rm container_name 36 37# Remove running container (force) 38docker rm -f container_name 39 40# Remove multiple containers 41docker rm container1 container2 container3 42 43# Remove all stopped containers 44docker container prune
Interacting with Containers
Execute Commands in Running Containers
Bash14 lines1# Execute command in running container 2docker exec container_name ls -la 3 4# Interactive bash shell 5docker exec -it container_name bash 6 7# Execute as specific user 8docker exec -u root container_name whoami 9 10# Execute with environment variables 11docker exec -e VAR=value container_name env 12 13# Execute in specific directory 14docker exec -w /app container_name pwd
Attach to Running Containers
Bash7 lines1# Attach to container (view output) 2docker attach container_name 3 4# Attach with no-stdin (read-only) 5docker attach --no-stdin container_name 6 7# Detach: Press Ctrl+P, then Ctrl+Q
View Container Logs
Bash17 lines1# View all logs 2docker logs container_name 3 4# Follow logs (like tail -f) 5docker logs -f container_name 6 7# Show last 100 lines 8docker logs --tail 100 container_name 9 10# Show logs since timestamp 11docker logs --since 2024-01-29 container_name 12 13# Show logs with timestamps 14docker logs -t container_name 15 16# Show logs from last 10 minutes 17docker logs --since 10m container_name
Copy Files To/From Containers
Bash11 lines1# Copy from host to container 2docker cp /host/file.txt container_name:/container/path/ 3 4# Copy from container to host 5docker cp container_name:/container/file.txt /host/path/ 6 7# Copy directory 8docker cp /host/dir/ container_name:/container/path/ 9 10# Copy from stopped container 11docker cp stopped_container:/app/data.json ./
Container Inspection and Stats
Bash26 lines1# Inspect container details 2docker inspect container_name 3 4# View specific information 5docker inspect --format='{{.State.Running}}' container_name 6 7# View container IP address 8docker inspect --format='{{.NetworkSettings.IPAddress}}' container_name 9 10# Real-time resource usage 11docker stats 12 13# Stats for specific container 14docker stats container_name 15 16# Stats without streaming 17docker stats --no-stream 18 19# View running processes 20docker top container_name 21 22# View port mappings 23docker port container_name 24 25# View container changes 26docker diff container_name
Container Resource Management
Bash11 lines1# Update container resources 2docker update --memory 1g --cpus 2 container_name 3 4# Update restart policy 5docker update --restart unless-stopped container_name 6 7# Rename container 8docker rename old_name new_name 9 10# Wait for container to stop 11docker wait container_name
Docker Volumes - Data Persistence
Understanding Docker Volumes
Why Volumes?
- Containers are ephemeral (data lost when container is removed)
- Volumes persist data beyond container lifecycle
- Share data between containers
- Better performance than bind mounts
- Managed by Docker
Types of Data Persistence
| Type | Description | Use Case |
|---|---|---|
| Volume | Managed by Docker | Database data, application state |
| Bind Mount | Direct host path | Development, config files |
| tmpfs | RAM storage | Temporary data, sensitive info |
Creating and Managing Volumes
Bash20 lines1# Create a volume 2docker volume create my-volume 3 4# Create with specific driver 5docker volume create --driver local my-volume 6 7# List all volumes 8docker volume ls 9 10# Inspect volume 11docker volume inspect my-volume 12 13# Remove volume 14docker volume rm my-volume 15 16# Remove all unused volumes 17docker volume prune 18 19# Remove all volumes (dangerous!) 20docker volume rm $(docker volume ls -q)
Using Volumes with Containers
Named Volumes
Bash11 lines1# Run container with named volume 2docker run -d \ 3 --name postgres \ 4 -v postgres-data:/var/lib/postgresql/data \ 5 postgres:latest 6 7# Multiple volumes 8docker run -d \ 9 -v app-data:/app/data \ 10 -v app-logs:/app/logs \ 11 myapp:latest
Anonymous Volumes
Bash5 lines1# Docker creates volume automatically 2docker run -d -v /app/data nginx 3 4# List anonymous volumes 5docker volume ls -f dangling=true
Bind Mounts
Bash19 lines1# Mount host directory 2docker run -d \ 3 -v /host/path:/container/path \ 4 nginx 5 6# Mount current directory 7docker run -d \ 8 -v $(pwd):/app \ 9 node:latest 10 11# Read-only mount 12docker run -d \ 13 -v /host/config:/etc/config:ro \ 14 nginx 15 16# Mount with specific permissions 17docker run -d \ 18 -v /host/path:/container/path:rw \ 19 nginx
tmpfs Mounts (RAM Storage)
Bash9 lines1# Mount tmpfs (data in RAM) 2docker run -d \ 3 --tmpfs /tmp \ 4 nginx 5 6# With size limit 7docker run -d \ 8 --tmpfs /tmp:size=100m \ 9 nginx
Volume Backup and Restore
Bash17 lines1# Backup volume to tar file 2docker run --rm \ 3 -v postgres-data:/data \ 4 -v $(pwd):/backup \ 5 ubuntu tar czf /backup/postgres-backup.tar.gz /data 6 7# Restore volume from backup 8docker run --rm \ 9 -v postgres-data:/data \ 10 -v $(pwd):/backup \ 11 ubuntu tar xzf /backup/postgres-backup.tar.gz -C / 12 13# Copy volume to another volume 14docker run --rm \ 15 -v old-volume:/from \ 16 -v new-volume:/to \ 17 ubuntu cp -av /from/. /to/
Sharing Volumes Between Containers
Bash17 lines1# Create shared volume 2docker volume create shared-data 3 4# Container 1 writes data 5docker run -d \ 6 --name writer \ 7 -v shared-data:/data \ 8 ubuntu bash -c "echo 'Hello' > /data/message.txt" 9 10# Container 2 reads data 11docker run --rm \ 12 -v shared-data:/data \ 13 ubuntu cat /data/message.txt 14 15# Multiple containers using same volume 16docker run -d --name app1 -v shared-data:/data nginx 17docker run -d --name app2 -v shared-data:/data nginx
Volume Best Practices
Bash16 lines1# Use named volumes for important data 2docker volume create db-data 3docker run -d -v db-data:/var/lib/mysql mysql 4 5# Use bind mounts for development 6docker run -d -v $(pwd):/app node:latest 7 8# Use tmpfs for sensitive temporary data 9docker run -d --tmpfs /tmp:mode=1777 nginx 10 11# Label volumes for organization 12docker volume create --label env=production db-data 13 14# Regular backups 15docker run --rm -v db-data:/data -v $(pwd):/backup \ 16 ubuntu tar czf /backup/db-$(date +%Y%m%d).tar.gz /data
Docker Networks
Understanding Docker Networking
Network Drivers:
| Driver | Description | Use Case |
|---|---|---|
| bridge | Default network, isolated from host | Single-host containers |
| host | Uses host's network directly | High performance needed |
| overlay | Multi-host networking | Docker Swarm, multi-host |
| macvlan | Assigns MAC address to container | Legacy apps, network monitoring |
| none | No networking | Complete isolation |
Network Management
Bash29 lines1# List networks 2docker network ls 3 4# Inspect network 5docker network inspect bridge 6 7# Create network 8docker network create my-network 9 10# Create with specific driver 11docker network create --driver bridge my-bridge 12 13# Create with subnet 14docker network create \ 15 --subnet=172.18.0.0/16 \ 16 --gateway=172.18.0.1 \ 17 my-network 18 19# Remove network 20docker network rm my-network 21 22# Remove all unused networks 23docker network prune 24 25# Connect container to network 26docker network connect my-network container_name 27 28# Disconnect container from network 29docker network disconnect my-network container_name
Container Networking Examples
Default Bridge Network
Bash5 lines1# Run on default bridge 2docker run -d --name web nginx 3 4# Containers can communicate via IP 5docker inspect web | grep IPAddress
Custom Bridge Network (Recommended)
Bash10 lines1# Create custom network 2docker network create my-app-network 3 4# Run containers on custom network 5docker run -d --name web --network my-app-network nginx 6docker run -d --name api --network my-app-network node:latest 7 8# Containers can communicate via name 9# Inside 'web' container: 10curl http://api:3000
Host Network
Bash5 lines1# Use host network (no isolation) 2docker run -d --network host nginx 3 4# Container uses host's network stack 5# Port bindings are ignored (-p doesn't work)
None Network
Bash4 lines1# No network (complete isolation) 2docker run -d --network none nginx 3 4# Container has no network access
Multi-Container Communication
Bash25 lines1# Create network 2docker network create app-tier 3 4# Database container 5docker run -d \ 6 --name postgres \ 7 --network app-tier \ 8 -e POSTGRES_PASSWORD=secret \ 9 postgres:latest 10 11# Backend container 12docker run -d \ 13 --name backend \ 14 --network app-tier \ 15 -e DB_HOST=postgres \ 16 -e DB_PASSWORD=secret \ 17 mybackend:latest 18 19# Frontend container 20docker run -d \ 21 --name frontend \ 22 --network app-tier \ 23 -p 80:80 \ 24 -e API_URL=http://backend:3000 \ 25 myfrontend:latest
Port Publishing
Bash20 lines1# Publish port (host:container) 2docker run -p 8080:80 nginx 3 4# Publish all exposed ports to random host ports 5docker run -P nginx 6 7# Publish to specific interface 8docker run -p 127.0.0.1:8080:80 nginx 9 10# Publish UDP port 11docker run -p 8080:80/udp nginx 12 13# Multiple ports 14docker run \ 15 -p 8080:80 \ 16 -p 8443:443 \ 17 nginx 18 19# View port mappings 20docker port container_name
Network Aliases
Bash15 lines1# Create container with network alias 2docker run -d \ 3 --name api \ 4 --network my-network \ 5 --network-alias api-service \ 6 myapi:latest 7 8# Now accessible as both 'api' and 'api-service' 9 10# Multiple aliases 11docker run -d \ 12 --network my-network \ 13 --network-alias web \ 14 --network-alias www \ 15 nginx
DNS and Service Discovery
Bash17 lines1# Custom DNS servers 2docker run --dns 8.8.8.8 nginx 3 4# Multiple DNS servers 5docker run \ 6 --dns 8.8.8.8 \ 7 --dns 8.8.4.4 \ 8 nginx 9 10# DNS search domains 11docker run --dns-search example.com nginx 12 13# Custom hostname 14docker run --hostname myapp nginx 15 16# Add entry to /etc/hosts 17docker run --add-host mydb:192.168.1.100 nginx
Creating Docker Images - Dockerfile
Dockerfile Basics
What is a Dockerfile?
- Text file with instructions to build a Docker image
- Each instruction creates a layer
- Layers are cached for faster builds
- Instructions are executed in order
Dockerfile Instructions
| Instruction | Purpose | Example |
|---|---|---|
CODE 1 line FROM | Base image | CODE 1 line FROM ubuntu:20.04 |
CODE 1 line RUN | Execute command | CODE 1 line RUN apt-get update |
CODE 1 line CMD | Default command | CODE 1 line CMD ["nginx", "-g", "daemon off;"] |
CODE 1 line ENTRYPOINT | Executable | CODE 1 line ENTRYPOINT ["python"] |
CODE 1 line COPY | Copy files | CODE 1 line COPY app.py /app/ |
CODE 1 line ADD | Copy files (with extraction) | CODE 1 line ADD archive.tar.gz /app/ |
CODE 1 line WORKDIR | Set working directory | CODE 1 line WORKDIR /app |
CODE 1 line ENV | Environment variable | CODE 1 line ENV NODE_ENV=production |
CODE 1 line EXPOSE | Document ports | CODE 1 line EXPOSE 80 |
CODE 1 line VOLUME | Create mount point | CODE 1 line VOLUME /data |
CODE 1 line USER | Set user | CODE 1 line USER node |
CODE 1 line ARG | Build argument | CODE 1 line ARG VERSION=1.0 |
CODE 1 line LABEL | Add metadata | CODE 1 line LABEL version="1.0" |
CODE 1 line HEALTHCHECK | Health check | CODE 1 line HEALTHCHECK CMD curl -f http://localhost/ |
Basic Dockerfile Examples
Simple Node.js Application
Dockerfile23 lines1# Use official Node.js image 2FROM node:18-alpine 3 4# Set working directory 5WORKDIR /app 6 7# Copy package files 8COPY package*.json ./ 9 10# Install dependencies 11RUN npm install --production 12 13# Copy application code 14COPY . . 15 16# Expose port 17EXPOSE 3000 18 19# Set user (security) 20USER node 21 22# Start application 23CMD ["node", "server.js"]
Python Application
Dockerfile20 lines1FROM python:3.11-slim 2 3WORKDIR /app 4 5# Copy requirements first (layer caching) 6COPY requirements.txt . 7 8# Install dependencies 9RUN pip install --no-cache-dir -r requirements.txt 10 11# Copy application 12COPY . . 13 14# Create non-root user 15RUN useradd -m appuser && chown -R appuser:appuser /app 16USER appuser 17 18EXPOSE 8000 19 20CMD ["python", "app.py"]
Static Website with Nginx
Dockerfile15 lines1FROM nginx:alpine 2 3# Remove default nginx config 4RUN rm /etc/nginx/conf.d/default.conf 5 6# Copy custom config 7COPY nginx.conf /etc/nginx/conf.d/ 8 9# Copy website files 10COPY dist/ /usr/share/nginx/html/ 11 12EXPOSE 80 13 14# Nginx runs in foreground by default 15CMD ["nginx", "-g", "daemon off;"]
Multi-Stage Builds
Why Multi-Stage?
- Smaller final images
- Separate build and runtime environments
- Keep build tools out of production image
Multi-Stage Build Example
Dockerfile21 lines1# Stage 1: Build 2FROM node:18 AS builder 3 4WORKDIR /app 5 6COPY package*.json ./ 7RUN npm install 8 9COPY . . 10RUN npm run build 11 12# Stage 2: Production 13FROM nginx:alpine 14 15# Copy built files from builder stage 16COPY /app/dist /usr/share/nginx/html 17COPY nginx.conf /etc/nginx/conf.d/default.conf 18 19EXPOSE 80 20 21CMD ["nginx", "-g", "daemon off;"]
Go Application Multi-Stage Build
Dockerfile23 lines1# Build stage 2FROM golang:1.21-alpine AS builder 3 4WORKDIR /app 5 6COPY go.mod go.sum ./ 7RUN go mod download 8 9COPY . . 10RUN CGO_ENABLED=0 GOOS=linux go build -o main . 11 12# Final stage 13FROM alpine:latest 14 15RUN apk --no-cache add ca-certificates 16 17WORKDIR /root/ 18 19COPY /app/main . 20 21EXPOSE 8080 22 23CMD ["./main"]
Building Images
Bash20 lines1# Build image from Dockerfile 2docker build -t myapp:latest . 3 4# Build with specific Dockerfile 5docker build -f Dockerfile.prod -t myapp:prod . 6 7# Build with build arguments 8docker build --build-arg VERSION=1.0 -t myapp:1.0 . 9 10# Build without cache 11docker build --no-cache -t myapp:latest . 12 13# Build and tag multiple times 14docker build -t myapp:latest -t myapp:v1.0 . 15 16# Show build output 17docker build --progress=plain -t myapp:latest . 18 19# Build specific stage in multi-stage 20docker build --target builder -t myapp:builder .
Advanced Dockerfile Techniques
Using ARG and ENV
Dockerfile25 lines1FROM node:18-alpine 2 3# Build argument (only during build) 4ARG NODE_ENV=production 5 6# Environment variable (available in container) 7ENV NODE_ENV=$NODE_ENV \ 8 PORT=3000 9 10WORKDIR /app 11 12COPY package*.json ./ 13 14# Use ARG in RUN 15RUN if [ "$NODE_ENV" = "production" ]; then \ 16 npm ci --only=production; \ 17 else \ 18 npm install; \ 19 fi 20 21COPY . . 22 23EXPOSE $PORT 24 25CMD ["node", "server.js"]
Health Checks
Dockerfile11 lines1FROM nginx:alpine 2 3COPY . /usr/share/nginx/html 4 5EXPOSE 80 6 7# Health check 8HEALTHCHECK \ 9 CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1 10 11CMD ["nginx", "-g", "daemon off;"]
Labels and Metadata
Dockerfile12 lines1FROM node:18-alpine 2 3LABEL maintainer="yourname@example.com" \ 4 version="1.0" \ 5 description="My awesome application" \ 6 org.opencontainers.image.source="https://github.com/user/repo" 7 8WORKDIR /app 9 10COPY . . 11 12CMD ["node", "server.js"]
Dockerfile Best Practices
Dockerfile39 lines1# Use specific tags, not 'latest' 2FROM node:18.16-alpine 3 4# Combine RUN commands to reduce layers 5RUN apk add --no-cache curl \ 6 && apk add --no-cache git \ 7 && npm install -g npm@latest 8 9# Order instructions by change frequency 10COPY package*.json ./ # Changes less often 11RUN npm install 12COPY . . # Changes frequently 13 14# Use .dockerignore file 15# Create .dockerignore: 16# node_modules 17# .git 18# .env 19# *.md 20 21# Run as non-root user 22RUN addgroup -g 1000 appuser && \ 23 adduser -D -u 1000 -G appuser appuser 24USER appuser 25 26# Use COPY instead of ADD (unless you need ADD features) 27COPY package.json . 28 29# Clean up in same layer 30RUN apt-get update && \ 31 apt-get install -y curl && \ 32 apt-get clean && \ 33 rm -rf /var/lib/apt/lists/* 34 35# Use multi-stage builds for smaller images 36FROM node:18 AS builder 37# ... build steps ... 38FROM node:18-alpine 39COPY /app/dist ./dist
Docker Compose
Introduction to Docker Compose
What is Docker Compose?
- Tool for defining and running multi-container applications
- Uses YAML file (docker-compose.yml) for configuration
- Simplifies complex container setups
- Manages multiple services, networks, and volumes
Benefits:
- Single command to start all services
- Declarative configuration
- Environment-specific configurations
- Easy service linking
- Volume and network management
Docker Compose File Structure
Basic docker-compose.yml:
YAML39 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 ports: 7 - "80:80" 8 volumes: 9 - ./html:/usr/share/nginx/html 10 networks: 11 - frontend 12 13 api: 14 build: ./api 15 ports: 16 - "3000:3000" 17 environment: 18 - NODE_ENV=production 19 depends_on: 20 - db 21 networks: 22 - frontend 23 - backend 24 25 db: 26 image: postgres:15 27 environment: 28 - POSTGRES_PASSWORD=secret 29 volumes: 30 - db-data:/var/lib/postgresql/data 31 networks: 32 - backend 33 34networks: 35 frontend: 36 backend: 37 38volumes: 39 db-data:
Complete MERN Stack Example
YAML79 lines1version: '3.8' 2 3services: 4 # MongoDB Database 5 mongo: 6 image: mongo:6 7 container_name: mern-mongo 8 restart: unless-stopped 9 environment: 10 MONGO_INITDB_ROOT_USERNAME: admin 11 MONGO_INITDB_ROOT_PASSWORD: secret123 12 volumes: 13 - mongo-data:/data/db 14 networks: 15 - mern-network 16 ports: 17 - "27017:27017" 18 19 # Backend API (Express) 20 backend: 21 build: 22 context: ./backend 23 dockerfile: Dockerfile 24 container_name: mern-backend 25 restart: unless-stopped 26 environment: 27 - NODE_ENV=production 28 - MONGO_URI=mongodb://admin:secret123@mongo:27017/myapp?authSource=admin 29 - PORT=5000 30 depends_on: 31 - mongo 32 volumes: 33 - ./backend:/app 34 - /app/node_modules 35 networks: 36 - mern-network 37 ports: 38 - "5000:5000" 39 40 # Frontend (React) 41 frontend: 42 build: 43 context: ./frontend 44 dockerfile: Dockerfile 45 container_name: mern-frontend 46 restart: unless-stopped 47 environment: 48 - REACT_APP_API_URL=http://localhost:5000 49 depends_on: 50 - backend 51 volumes: 52 - ./frontend:/app 53 - /app/node_modules 54 networks: 55 - mern-network 56 ports: 57 - "3000:3000" 58 59 # Nginx Reverse Proxy 60 nginx: 61 image: nginx:alpine 62 container_name: mern-nginx 63 restart: unless-stopped 64 ports: 65 - "80:80" 66 volumes: 67 - ./nginx.conf:/etc/nginx/nginx.conf:ro 68 depends_on: 69 - frontend 70 - backend 71 networks: 72 - mern-network 73 74networks: 75 mern-network: 76 driver: bridge 77 78volumes: 79 mongo-data:
WordPress with MySQL
YAML41 lines1version: '3.8' 2 3services: 4 db: 5 image: mysql:8.0 6 container_name: wordpress-db 7 restart: unless-stopped 8 environment: 9 MYSQL_ROOT_PASSWORD: rootpassword 10 MYSQL_DATABASE: wordpress 11 MYSQL_USER: wpuser 12 MYSQL_PASSWORD: wppassword 13 volumes: 14 - db-data:/var/lib/mysql 15 networks: 16 - wordpress-network 17 18 wordpress: 19 depends_on: 20 - db 21 image: wordpress:latest 22 container_name: wordpress-app 23 restart: unless-stopped 24 ports: 25 - "8080:80" 26 environment: 27 WORDPRESS_DB_HOST: db:3306 28 WORDPRESS_DB_USER: wpuser 29 WORDPRESS_DB_PASSWORD: wppassword 30 WORDPRESS_DB_NAME: wordpress 31 volumes: 32 - wordpress-data:/var/www/html 33 networks: 34 - wordpress-network 35 36networks: 37 wordpress-network: 38 39volumes: 40 db-data: 41 wordpress-data:
Docker Compose Commands
Starting and Stopping Services
Bash29 lines1# Start all services 2docker compose up 3 4# Start in background (detached) 5docker compose up -d 6 7# Start specific service 8docker compose up -d web 9 10# Build images before starting 11docker compose up --build 12 13# Force recreate containers 14docker compose up --force-recreate 15 16# Stop all services 17docker compose stop 18 19# Stop specific service 20docker compose stop web 21 22# Stop and remove containers 23docker compose down 24 25# Stop and remove containers, volumes, networks 26docker compose down -v 27 28# Stop and remove with images 29docker compose down --rmi all
Building and Managing Images
Bash14 lines1# Build or rebuild services 2docker compose build 3 4# Build without cache 5docker compose build --no-cache 6 7# Build specific service 8docker compose build web 9 10# Pull latest images 11docker compose pull 12 13# Push images to registry 14docker compose push
Viewing and Managing Services
Bash32 lines1# List running services 2docker compose ps 3 4# List all services (including stopped) 5docker compose ps -a 6 7# View logs 8docker compose logs 9 10# Follow logs 11docker compose logs -f 12 13# View logs for specific service 14docker compose logs -f web 15 16# View last 100 lines 17docker compose logs --tail=100 18 19# Execute command in service 20docker compose exec web sh 21 22# Run one-off command 23docker compose run web npm test 24 25# View resource usage 26docker compose top 27 28# Validate compose file 29docker compose config 30 31# View processed config 32docker compose config --services
Scaling Services
Bash8 lines1# Scale service to multiple instances 2docker compose up -d --scale web=3 3 4# Scale in existing deployment 5docker compose scale web=5 6 7# Scale multiple services 8docker compose up -d --scale web=3 --scale api=2
Advanced Docker Compose Features
Environment Variables
YAML11 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 environment: 7 - NGINX_HOST=example.com 8 - NGINX_PORT=80 9 env_file: 10 - .env 11 - .env.production
.env file:
Bash3 lines1POSTGRES_USER=admin 2POSTGRES_PASSWORD=secret123 3NODE_ENV=production
Build Configuration
YAML14 lines1version: '3.8' 2 3services: 4 webapp: 5 build: 6 context: ./app 7 dockerfile: Dockerfile.prod 8 args: 9 - NODE_ENV=production 10 - VERSION=1.0.0 11 cache_from: 12 - myapp:latest 13 target: production 14 image: myapp:latest
Health Checks
YAML11 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 healthcheck: 7 test: ["CMD", "curl", "-f", "http://localhost"] 8 interval: 30s 9 timeout: 10s 10 retries: 3 11 start_period: 40s
Resource Limits
YAML13 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 deploy: 7 resources: 8 limits: 9 cpus: '0.50' 10 memory: 512M 11 reservations: 12 cpus: '0.25' 13 memory: 256M
Restart Policies
YAML6 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 restart: unless-stopped # no, always, on-failure, unless-stopped
Depends On with Conditions
YAML16 lines1version: '3.8' 2 3services: 4 web: 5 image: nginx:alpine 6 depends_on: 7 db: 8 condition: service_healthy 9 10 db: 11 image: postgres:15 12 healthcheck: 13 test: ["CMD-SHELL", "pg_isready -U postgres"] 14 interval: 10s 15 timeout: 5s 16 retries: 5
Docker Registry & Hub
Docker Hub
What is Docker Hub?
- Default public registry for Docker images
- Free public repositories
- Private repositories (limited on free plan)
- Automated builds
- Official images from vendors
Working with Docker Hub
Bash25 lines1# Login to Docker Hub 2docker login 3 4# Login with username 5docker login -u username 6 7# Logout 8docker logout 9 10# Search for images 11docker search ubuntu 12 13# Pull image 14docker pull ubuntu:20.04 15 16# Tag image for push 17docker tag myapp:latest username/myapp:latest 18 19# Push image to Docker Hub 20docker push username/myapp:latest 21 22# Push with multiple tags 23docker tag myapp:latest username/myapp:v1.0 24docker push username/myapp:v1.0 25docker push username/myapp:latest
Creating Images for Docker Hub
Bash11 lines1# Build image with namespace 2docker build -t username/myapp:latest . 3 4# Tag existing image 5docker tag myapp:latest username/myapp:latest 6 7# Push to Docker Hub 8docker push username/myapp:latest 9 10# Pull your image 11docker pull username/myapp:latest
Private Docker Registry
Running Private Registry
Bash16 lines1# Run local registry 2docker run -d \ 3 -p 5000:5000 \ 4 --name registry \ 5 --restart=always \ 6 -v registry-data:/var/lib/registry \ 7 registry:2 8 9# Tag image for private registry 10docker tag myapp:latest localhost:5000/myapp:latest 11 12# Push to private registry 13docker push localhost:5000/myapp:latest 14 15# Pull from private registry 16docker pull localhost:5000/myapp:latest
Secure Private Registry with TLS
Bash10 lines1# Run registry with TLS 2docker run -d \ 3 -p 5000:5000 \ 4 --name registry \ 5 --restart=always \ 6 -v /path/to/certs:/certs \ 7 -v registry-data:/var/lib/registry \ 8 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ 9 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ 10 registry:2
Registry with Authentication
Bash20 lines1# Create htpasswd file 2mkdir auth 3docker run --rm \ 4 --entrypoint htpasswd \ 5 httpd:2 -Bbn username password > auth/htpasswd 6 7# Run registry with authentication 8docker run -d \ 9 -p 5000:5000 \ 10 --name registry \ 11 --restart=always \ 12 -v $(pwd)/auth:/auth \ 13 -v registry-data:/var/lib/registry \ 14 -e "REGISTRY_AUTH=htpasswd" \ 15 -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ 16 -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \ 17 registry:2 18 19# Login to private registry 20docker login localhost:5000
Alternative Registries
Bash19 lines1# Google Container Registry 2docker tag myapp gcr.io/project-id/myapp:latest 3docker push gcr.io/project-id/myapp:latest 4 5# Amazon ECR 6aws ecr get-login-password --region region | docker login --username AWS \ 7 --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com 8docker tag myapp:latest aws_account_id.dkr.ecr.region.amazonaws.com/myapp:latest 9docker push aws_account_id.dkr.ecr.region.amazonaws.com/myapp:latest 10 11# Azure Container Registry 12docker login myregistry.azurecr.io 13docker tag myapp myregistry.azurecr.io/myapp:latest 14docker push myregistry.azurecr.io/myapp:latest 15 16# GitHub Container Registry 17echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin 18docker tag myapp ghcr.io/username/myapp:latest 19docker push ghcr.io/username/myapp:latest
Docker Best Practices
Image Building Best Practices
Minimize Layer Count
Dockerfile10 lines1# Bad - Multiple layers 2RUN apt-get update 3RUN apt-get install -y curl 4RUN apt-get install -y git 5 6# Good - Single layer 7RUN apt-get update && \ 8 apt-get install -y curl git && \ 9 apt-get clean && \ 10 rm -rf /var/lib/apt/lists/*
Order Instructions by Change Frequency
Dockerfile6 lines1# Install dependencies first (changes rarely) 2COPY package.json package-lock.json ./ 3RUN npm ci --only=production 4 5# Copy source code last (changes frequently) 6COPY . .
Use .dockerignore
Bash12 lines1# .dockerignore 2node_modules 3npm-debug.log 4.git 5.gitignore 6.env 7.env.local 8*.md 9.DS_Store 10dist 11coverage 12.vscode
Use Multi-Stage Builds
Dockerfile14 lines1# Build stage - larger image 2FROM node:18 AS builder 3WORKDIR /app 4COPY package*.json ./ 5RUN npm install 6COPY . . 7RUN npm run build 8 9# Production stage - smaller image 10FROM node:18-alpine 11WORKDIR /app 12COPY /app/dist ./dist 13COPY /app/node_modules ./node_modules 14CMD ["node", "dist/server.js"]
Use Specific Image Tags
Dockerfile8 lines1# Bad - tag can change 2FROM node:latest 3 4# Better - specific version 5FROM node:18 6 7# Best - specific version and variant 8FROM node:18.16-alpine
Security Best Practices
Run as Non-Root User
Dockerfile13 lines1FROM node:18-alpine 2 3# Create app user 4RUN addgroup -g 1001 appuser && \ 5 adduser -D -u 1001 -G appuser appuser 6 7WORKDIR /app 8COPY . . 9 10# Switch to non-root user 11USER appuser 12 13CMD ["node", "server.js"]
Scan Images for Vulnerabilities
Bash8 lines1# Scan image with Docker Scout (built-in) 2docker scout cves myapp:latest 3 4# Scan with Trivy 5trivy image myapp:latest 6 7# Scan with Snyk 8snyk container test myapp:latest
Use Official Base Images
Dockerfile5 lines1# Use official images from Docker Hub 2FROM node:18-alpine 3FROM python:3.11-slim 4FROM nginx:alpine 5FROM postgres:15-alpine
Minimize Attack Surface
Dockerfile8 lines1# Use slim or alpine variants 2FROM python:3.11-slim 3 4# Remove unnecessary packages 5RUN apt-get update && \ 6 apt-get install -y --no-install-recommends curl && \ 7 apt-get clean && \ 8 rm -rf /var/lib/apt/lists/*
Container Runtime Best Practices
Use Resource Limits
Bash6 lines1# Limit memory and CPU 2docker run -d \ 3 --name myapp \ 4 --memory="512m" \ 5 --cpus="1.0" \ 6 myapp:latest
Set Restart Policies
Bash5 lines1# Restart on failure 2docker run -d \ 3 --name myapp \ 4 --restart unless-stopped \ 5 myapp:latest
Use Health Checks
Dockerfile4 lines1FROM nginx:alpine 2 3HEALTHCHECK \ 4 CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
Read-Only Root Filesystem
Bash6 lines1# Run with read-only root filesystem 2docker run -d \ 3 --read-only \ 4 --tmpfs /tmp \ 5 --tmpfs /run \ 6 myapp:latest
Performance Best Practices
Use BuildKit for Faster Builds
Bash9 lines1# Enable BuildKit 2export DOCKER_BUILDKIT=1 3 4# Build with BuildKit 5docker build -t myapp:latest . 6 7# Use cache mounts (BuildKit feature) 8# In Dockerfile: 9RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
Layer Caching
Dockerfile6 lines1# Copy package files first 2COPY package.json package-lock.json ./ 3RUN npm ci 4 5# Copy source code after 6COPY . .
Parallel Builds
Bash5 lines1# Build multiple images in parallel 2docker compose build --parallel 3 4# Build with max parallelism 5docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
Monitoring & Logging
Container Logs
Bash17 lines1# View logs 2docker logs container_name 3 4# Follow logs 5docker logs -f container_name 6 7# Last 100 lines 8docker logs --tail 100 container_name 9 10# Logs since timestamp 11docker logs --since 2024-01-29T10:00:00 container_name 12 13# Logs with timestamps 14docker logs -t container_name 15 16# Logs from last hour 17docker logs --since 1h container_name
Resource Monitoring
Bash11 lines1# Real-time stats for all containers 2docker stats 3 4# Stats for specific container 5docker stats container_name 6 7# Stats without streaming 8docker stats --no-stream 9 10# Format output 11docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
System Information
Bash11 lines1# System-wide information 2docker system df 3 4# Detailed system info 5docker system df -v 6 7# Docker info 8docker info 9 10# Version information 11docker version
Events Monitoring
Bash11 lines1# Watch Docker events 2docker events 3 4# Events since time 5docker events --since '2024-01-29T10:00:00' 6 7# Events for specific container 8docker events --filter container=myapp 9 10# Events for specific type 11docker events --filter type=container
Container Inspection
Bash11 lines1# Inspect container 2docker inspect container_name 3 4# Get specific information 5docker inspect --format='{{.State.Status}}' container_name 6 7# Get IP address 8docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name 9 10# Get all environment variables 11docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' container_name
Health Checks
Bash5 lines1# View health status 2docker inspect --format='{{.State.Health.Status}}' container_name 3 4# View health check logs 5docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' container_name
Third-Party Monitoring Tools
Prometheus + Grafana
YAML23 lines1version: '3.8' 2 3services: 4 prometheus: 5 image: prom/prometheus 6 volumes: 7 - ./prometheus.yml:/etc/prometheus/prometheus.yml 8 - prometheus-data:/prometheus 9 ports: 10 - "9090:9090" 11 12 grafana: 13 image: grafana/grafana 14 depends_on: 15 - prometheus 16 ports: 17 - "3000:3000" 18 volumes: 19 - grafana-data:/var/lib/grafana 20 21volumes: 22 prometheus-data: 23 grafana-data:
cAdvisor (Container Advisor)
Bash8 lines1docker run -d \ 2 --name=cadvisor \ 3 --volume=/:/rootfs:ro \ 4 --volume=/var/run:/var/run:ro \ 5 --volume=/sys:/sys:ro \ 6 --volume=/var/lib/docker/:/var/lib/docker:ro \ 7 --publish=8080:8080 \ 8 google/cadvisor:latest
Troubleshooting
Common Issues and Solutions
Container Won't Start
Symptoms:
Bash2 lines1docker ps -a 2# Shows container with status "Exited (1)"
Diagnosis:
Bash8 lines1# Check logs 2docker logs container_name 3 4# Inspect container 5docker inspect container_name 6 7# Check events 8docker events --filter container=container_name
Common Causes:
- Application crashes immediately
- Missing environment variables
- Port already in use
- Volume permission issues
Solutions:
Bash8 lines1# Run interactively to debug 2docker run -it --entrypoint /bin/sh image_name 3 4# Check if port is in use 5netstat -tulpn | grep :8080 6 7# Fix volume permissions 8sudo chown -R 1000:1000 /host/path
Can't Connect to Container
Check network:
Bash11 lines1# Inspect network 2docker network inspect bridge 3 4# Check container IP 5docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name 6 7# Test connectivity 8docker exec container_name ping -c 2 google.com 9 10# Check port mappings 11docker port container_name
Out of Disk Space
Bash14 lines1# Check disk usage 2docker system df 3 4# Clean up 5docker system prune 6 7# Remove unused images 8docker image prune -a 9 10# Remove unused volumes 11docker volume prune 12 13# Remove everything (careful!) 14docker system prune -a --volumes
Container Performance Issues
Bash8 lines1# Check resource usage 2docker stats container_name 3 4# Inspect container limits 5docker inspect --format='{{.HostConfig.Memory}}' container_name 6 7# Update resource limits 8docker update --memory 1g --cpus 2 container_name
Build Failures
Cache issues:
Bash5 lines1# Build without cache 2docker build --no-cache -t myapp:latest . 3 4# Clear build cache 5docker builder prune
Network issues:
Bash8 lines1# Build with custom DNS 2docker build --dns 8.8.8.8 -t myapp:latest . 3 4# Use build-time proxy 5docker build \ 6 --build-arg HTTP_PROXY=http://proxy:8080 \ 7 --build-arg HTTPS_PROXY=http://proxy:8080 \ 8 -t myapp:latest .
Permission Denied Errors
Docker socket:
Bash5 lines1# Add user to docker group 2sudo usermod -aG docker $USER 3 4# Reboot or run 5newgrp docker
Volume permissions:
Bash8 lines1# Check permissions 2ls -la /host/path 3 4# Fix ownership 5sudo chown -R $(id -u):$(id -g) /host/path 6 7# Or use user mapping in Dockerfile 8USER 1000:1000
Debugging Techniques
Bash20 lines1# Run container with shell 2docker run -it --entrypoint /bin/sh image_name 3 4# Override command 5docker run -it image_name /bin/bash 6 7# Inspect running container 8docker exec -it container_name /bin/sh 9 10# Check container processes 11docker top container_name 12 13# View container changes 14docker diff container_name 15 16# Export container filesystem 17docker export container_name > container.tar 18 19# Copy files from container 20docker cp container_name:/app/log.txt ./
Docker Daemon Issues
Bash11 lines1# Check Docker service status 2systemctl status docker 3 4# Restart Docker service 5sudo systemctl restart docker 6 7# View Docker daemon logs 8journalctl -u docker.service 9 10# Check Docker daemon config 11cat /etc/docker/daemon.json
Security Best Practices
Container Security
Run as Non-Root
Dockerfile12 lines1# Create and use non-root user 2FROM node:18-alpine 3 4RUN addgroup -g 1001 appgroup && \ 5 adduser -D -u 1001 -G appgroup appuser 6 7WORKDIR /app 8COPY . . 9 10USER appuser 11 12CMD ["node", "server.js"]
Use Read-Only Root Filesystem
Bash5 lines1# Run with read-only root 2docker run -d \ 3 --read-only \ 4 --tmpfs /tmp:rw,noexec,nosuid \ 5 myapp:latest
Drop Unnecessary Capabilities
Bash5 lines1# Drop all capabilities and add only needed ones 2docker run -d \ 3 --cap-drop ALL \ 4 --cap-add NET_BIND_SERVICE \ 5 myapp:latest
Use Security Scanning
Bash12 lines1# Scan with Docker Scout 2docker scout cves myapp:latest 3 4# Scan with Trivy 5trivy image myapp:latest 6 7# Scan with Snyk 8snyk container test myapp:latest 9 10# Scan with Clair 11docker run -d --name clair arminc/clair-db 12docker run -p 6060:6060 -d --link clair:postgres --name clair arminc/clair-local-scan
Image Security
Use Trusted Base Images
Dockerfile8 lines1# Use official images 2FROM node:18-alpine 3 4# Or minimal images 5FROM gcr.io/distroless/nodejs:18 6 7# Verify image digest 8FROM node:18-alpine@sha256:abc123...
Sign Images
Bash8 lines1# Enable Docker Content Trust 2export DOCKER_CONTENT_TRUST=1 3 4# Push signed image 5docker push username/myapp:latest 6 7# Pull will verify signature automatically 8docker pull username/myapp:latest
Multi-Stage Build for Minimal Images
Dockerfile9 lines1FROM node:18 AS builder 2WORKDIR /app 3COPY . . 4RUN npm ci && npm run build 5 6FROM gcr.io/distroless/nodejs:18 7WORKDIR /app 8COPY /app/dist ./dist 9CMD ["dist/server.js"]
Network Security
Use Custom Networks
Bash6 lines1# Create isolated network 2docker network create --driver bridge app-network 3 4# Run containers on custom network 5docker run -d --name app1 --network app-network myapp:latest 6docker run -d --name app2 --network app-network myapp:latest
Limit Network Exposure
Bash6 lines1# Bind to localhost only 2docker run -d -p 127.0.0.1:8080:80 nginx 3 4# Don't publish all ports 5docker run -d -p 8080:80 nginx # Good 6# Avoid: docker run -d -P nginx # Publishes all ports
Secrets Management
Use Docker Secrets (Swarm)
Bash9 lines1# Create secret 2echo "my-secret-password" | docker secret create db_password - 3 4# Use in service 5docker service create \ 6 --name mysql \ 7 --secret db_password \ 8 -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_password \ 9 mysql:8.0
Environment Variables (Less Secure)
Bash7 lines1# Use .env file 2docker run --env-file .env myapp:latest 3 4# Better: Use secret management tools 5# - HashiCorp Vault 6# - AWS Secrets Manager 7# - Azure Key Vault
Security Checklist
- Run containers as non-root user
- Use official or verified base images
- Scan images for vulnerabilities regularly
- Use specific image tags, not 'latest'
- Keep base images updated
- Use read-only root filesystem when possible
- Drop unnecessary capabilities
- Use custom networks for isolation
- Don't store secrets in images
- Limit resource usage (CPU, memory)
- Enable Docker Content Trust
- Use multi-stage builds
- Implement health checks
- Monitor and log container activity
- Regular security audits
Quick Reference Card
Essential Docker Commands
Bash48 lines1# Images 2docker pull image:tag # Pull image 3docker images # List images 4docker rmi image # Remove image 5docker build -t name . # Build image 6docker tag source target # Tag image 7 8# Containers 9docker run -d image # Run container 10docker ps # List running containers 11docker ps -a # List all containers 12docker stop container # Stop container 13docker start container # Start container 14docker restart container # Restart container 15docker rm container # Remove container 16docker exec -it container bash # Execute command 17 18# Logs & Monitoring 19docker logs -f container # Follow logs 20docker stats # Resource usage 21docker inspect container # Detailed info 22docker top container # Running processes 23 24# Volumes 25docker volume create vol # Create volume 26docker volume ls # List volumes 27docker volume rm vol # Remove volume 28docker volume prune # Remove unused volumes 29 30# Networks 31docker network create net # Create network 32docker network ls # List networks 33docker network rm net # Remove network 34docker network inspect net # Inspect network 35 36# System 37docker system df # Disk usage 38docker system prune # Clean up 39docker info # System info 40docker version # Version info 41 42# Docker Compose 43docker compose up -d # Start services 44docker compose down # Stop services 45docker compose logs -f # View logs 46docker compose ps # List services 47docker compose build # Build images 48docker compose pull # Pull images
Common Docker Run Options
Bash13 lines1docker run \ 2 -d \ # Detached mode 3 --name myapp \ # Container name 4 -p 8080:80 \ # Port mapping 5 -v /host:/container \ # Volume mount 6 -e "VAR=value" \ # Environment variable 7 --network mynet \ # Custom network 8 --restart unless-stopped \ # Restart policy 9 --memory 512m \ # Memory limit 10 --cpus 1.0 \ # CPU limit 11 --user 1000:1000 \ # Run as user 12 --read-only \ # Read-only root 13 myimage:latest # Image name
Dockerfile Template
Dockerfile37 lines1# Base image 2FROM node:18-alpine 3 4# Metadata 5LABEL maintainer="your@email.com" 6 7# Install dependencies 8RUN apk add --no-cache curl 9 10# Create app user 11RUN addgroup -g 1001 appuser && \ 12 adduser -D -u 1001 -G appuser appuser 13 14# Set working directory 15WORKDIR /app 16 17# Copy package files 18COPY package*.json ./ 19 20# Install dependencies 21RUN npm ci --only=production 22 23# Copy application 24COPY . . 25 26# Switch to non-root user 27USER appuser 28 29# Expose port 30EXPOSE 3000 31 32# Health check 33HEALTHCHECK \ 34 CMD node healthcheck.js || exit 1 35 36# Start application 37CMD ["node", "server.js"]
Docker Compose Template
YAML47 lines1version: '3.8' 2 3services: 4 app: 5 build: 6 context: . 7 dockerfile: Dockerfile 8 container_name: myapp 9 restart: unless-stopped 10 ports: 11 - "3000:3000" 12 environment: 13 - NODE_ENV=production 14 env_file: 15 - .env 16 volumes: 17 - ./app:/app 18 - /app/node_modules 19 networks: 20 - app-network 21 depends_on: 22 - db 23 healthcheck: 24 test: ["CMD", "curl", "-f", "http://localhost:3000/health"] 25 interval: 30s 26 timeout: 10s 27 retries: 3 28 29 db: 30 image: postgres:15-alpine 31 container_name: postgres 32 restart: unless-stopped 33 environment: 34 POSTGRES_USER: user 35 POSTGRES_PASSWORD: password 36 POSTGRES_DB: mydb 37 volumes: 38 - postgres-data:/var/lib/postgresql/data 39 networks: 40 - app-network 41 42networks: 43 app-network: 44 driver: bridge 45 46volumes: 47 postgres-data:
Conclusion
Docker has revolutionized how we build, ship, and run applications. This comprehensive guide has covered everything from basic concepts to advanced production practices.
Key Takeaways:
- Docker containers provide consistency across environments
- Images are built in layers and should be optimized for size and security
- Docker Compose simplifies multi-container applications
- Always follow security best practices - run as non-root, scan images, use secrets properly
- Monitor and log your containers in production
- Use multi-stage builds for smaller, more secure images
- Leverage Docker networks for container isolation and communication
Best Practices to Remember:
- Use specific image tags, never rely on 'latest'
- Run containers as non-root users
- Implement health checks for all services
- Use .dockerignore to reduce build context
- Scan images for vulnerabilities regularly
- Keep base images updated
- Use multi-stage builds for production
- Implement proper logging and monitoring
- Use volumes for persistent data
- Regular cleanup of unused resources
Next Steps:
- Practice building and running containers
- Learn Docker Swarm or Kubernetes for orchestration
- Implement CI/CD pipelines with Docker
- Explore advanced networking and storage options
- Study container security in depth
- Build production-ready applications
Remember: Docker is a powerful tool, but it requires understanding of both its capabilities and limitations. Start simple, follow best practices, and gradually incorporate more advanced features as needed.
Happy containerizing! 🐳🚀
Last updated: January 2025
Additional Resources
Official Documentation
- Docker Documentation
- Docker Hub
- Dockerfile Reference
- Docker Compose Documentation
- Docker CLI Reference
Learning Resources
Security Resources
Tools and Utilities
- Docker Scout - Image vulnerability scanning
- Trivy - Vulnerability scanner
- Hadolint - Dockerfile linter
- Dive - Image layer analyzer
- Portainer - Container management UI
- Watchtower - Automatic container updates
Community and Forums
Books
- "Docker Deep Dive" by Nigel Poulton
- "Docker in Action" by Jeff Nickoloff
- "Docker: Up & Running" by Karl Matthias and Sean Kane
- "The Docker Book" by James Turnbull
Video Courses
Related Technologies
- Kubernetes - Container orchestration
- Docker Swarm - Native clustering
- Podman - Daemonless container engine
- containerd - Industry-standard container runtime
- BuildKit - Next-gen builder