Skip to content

Docker

Overview

Docker is a containerization platform that packages applications and dependencies into isolated, lightweight containers for consistent deployment across environments.


Core Docker Concepts

Container vs Virtual Machine

Aspect Container Virtual Machine
Size MB GB
Startup Time Seconds Minutes
OS Shared kernel Full OS
Isolation Process-level Hardware-level
Resource Usage Minimal Significant
Portability Excellent Good

Docker Architecture

┌─────────────────────────────────┐
│     Docker Client (CLI)         │
└──────────────┬──────────────────┘
               │
┌──────────────▼──────────────────┐
│     Docker Daemon               │
│  (Container Runtime)            │
└──────────────┬──────────────────┘
               │
     ┌─────────┼─────────┐
     │         │         │
  Images   Containers Networks  Volumes

Docker Installation

Linux

# Update system
sudo apt update

# Install Docker
sudo apt install -y docker.io

# Start Docker daemon
sudo systemctl start docker

# Enable Docker on boot
sudo systemctl enable docker

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

Verify Installation

# Check Docker version
docker --version

# Run Hello World
docker run hello-world

# Check Docker info
docker info

Docker Images

Understanding Images

A Docker image is a lightweight, standalone executable package containing all code, runtime, system tools, and libraries.

Dockerfile Structure

# Base image
FROM ubuntu:22.04

# Set working directory
WORKDIR /app

# Install dependencies
RUN apt-get update && \
    apt-get install -y python3 python3-pip && \
    rm -rf /var/lib/apt/lists/*

# Copy application code
COPY . .

# Install Python dependencies
RUN pip3 install -r requirements.txt

# Expose port
EXPOSE 5000

# Define environment variable
ENV FLASK_APP=app.py

# Set startup command
CMD ["python3", "app.py"]

Build Image

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

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

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

Image Commands

# List images
docker images

# Search images on Docker Hub
docker search ubuntu

# Pull image from registry
docker pull ubuntu:22.04

# Remove image
docker rmi myapp:1.0

# Tag image
docker tag myapp:1.0 myrepo/myapp:latest

# Push to registry
docker push myrepo/myapp:latest

# Inspect image
docker inspect myapp:1.0

# View image history
docker history myapp:1.0

Image Best Practices

Practice Benefit Example
Use specific base image tags Reproducibility FROM ubuntu:22.04 not FROM ubuntu:latest
Minimize layers Reduce image size Combine RUN commands
Clean up in same layer Smaller images apt-get clean && rm -rf /var/lib/apt/lists/*
Use .dockerignore Skip unnecessary files *.log, .git, node_modules
Multi-stage builds Separate build and runtime Build stage → production stage

Docker Containers

Run Containers

# Run container
docker run -d -p 8080:80 --name myapp nginx

# Run with environment variables
docker run -d -e DB_HOST=localhost -e DB_USER=admin myapp

# Run with volume mount
docker run -d -v /host/path:/container/path myapp

# Run with resource limits
docker run -d -m 512m --cpus=1 myapp

# Run interactively
docker run -it ubuntu /bin/bash

# Run with restart policy
docker run -d --restart=always myapp

# Run as specific user
docker run -d --user 1000:1000 myapp

Container Commands

# List running containers
docker ps

# List all containers
docker ps -a

# View container logs
docker logs myapp

# Follow container logs
docker logs -f myapp

# Stop container
docker stop myapp

# Start container
docker start myapp

# Restart container
docker restart myapp

# Remove container
docker rm myapp

# Execute command in container
docker exec -it myapp bash

# Copy files to/from container
docker cp myapp:/app/data.txt ./
docker cp ./config.yml myapp:/app/

# Inspect container
docker inspect myapp

# View container processes
docker top myapp

# View container resource usage
docker stats myapp

# View container port mappings
docker port myapp

Container Configuration

Port Mapping

# Map single port
docker run -p 8080:80 nginx
# Host port 8080 → Container port 80

# Map multiple ports
docker run -p 8080:80 -p 443:443 nginx

# Map to random host port
docker run -p 80 nginx

# Map all exposed ports
docker run -P nginx

Environment Variables

# Pass single variable
docker run -e APP_ENV=production myapp

# Pass multiple variables
docker run -e DB_HOST=localhost -e DB_PORT=5432 myapp

# Load from file
docker run --env-file .env myapp

Volume Management

# Named volume
docker run -v mydata:/data myapp

# Bind mount
docker run -v /host/path:/container/path myapp

# Read-only volume
docker run -v /host/path:/container/path:ro myapp

# List volumes
docker volume ls

# Inspect volume
docker volume inspect mydata

# Remove volume
docker volume rm mydata

# Clean up unused volumes
docker volume prune

Docker Networks

Network Types

Type Use Case Example
Bridge Default, single host docker run myapp
Host Performance critical docker run --net=host myapp
Overlay Multi-host (Swarm/K8s) Docker Swarm networks
None No networking docker run --net=none myapp

Network Commands

# List networks
docker network ls

# Create network
docker network create mynetwork

# Run container on network
docker run -d --network mynetwork --name app1 myapp
docker run -d --network mynetwork --name app2 myapp

# Connect container to network
docker network connect mynetwork running_container

# Disconnect container
docker network disconnect mynetwork container_name

# Inspect network
docker network inspect mynetwork

# Remove network
docker network rm mynetwork

Container Communication

# Containers on same network can communicate by name
# Inside container:
ping app1  # Resolves to app1's IP

# Expose ports for external access
docker run -p 3000:3000 webapp

Docker Compose

Docker Compose File

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8080:80"
    environment:
      - DB_HOST=database
      - DB_USER=admin
    depends_on:
      - database
    volumes:
      - ./app:/app
    networks:
      - mynetwork
    restart: unless-stopped

  database:
    image: postgres:15
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    networks:
      - mynetwork
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    networks:
      - mynetwork

volumes:
  db_data:

networks:
  mynetwork:
    driver: bridge

Docker Compose Commands

# Start services
docker-compose up -d

# View logs
docker-compose logs -f

# Stop services
docker-compose stop

# Stop and remove containers
docker-compose down

# Remove volumes too
docker-compose down -v

# Execute command in service
docker-compose exec web bash

# View running services
docker-compose ps

# Restart services
docker-compose restart

# Build services
docker-compose build

Docker Registry

Docker Hub

# Login to Docker Hub
docker login

# Push image
docker tag myapp:1.0 username/myapp:1.0
docker push username/myapp:1.0

# Pull image
docker pull username/myapp:1.0

# Logout
docker logout

Private Registry

# Run private registry
docker run -d -p 5000:5000 registry:2

# Tag image for private registry
docker tag myapp:1.0 localhost:5000/myapp:1.0

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

# Pull from private registry
docker pull localhost:5000/myapp:1.0

Multi-stage Builds

Reducing Image Size

# Stage 1: Build
FROM golang:1.20 as builder
WORKDIR /build
COPY . .
RUN go build -o app .

# Stage 2: Runtime
FROM alpine:latest
WORKDIR /app
COPY --from=builder /build/app .
EXPOSE 8080
CMD ["./app"]

Result: Image size reduced from ~900MB to ~15MB


Docker Best Practices

Practice Benefit Example
Use Alpine base images Minimal size FROM alpine:latest
One process per container Simplicity & debugging Single service
Health checks Auto recovery HEALTHCHECK CMD curl localhost
Security scanning Vulnerability detection docker scan myapp:1.0
Non-root user Security USER appuser
Read-only root Security docker run --read-only
Resource limits Stability -m 512m --cpus=1
Distroless images Security & size FROM gcr.io/distroless/base

Troubleshooting

Common Issues

# Container exits immediately
docker logs container_name  # Check logs

# Port already in use
docker ps  # Find container using port
docker stop container_name

# Permission denied
sudo usermod -aG docker $USER
newgrp docker

# Out of disk space
docker system prune -a  # Remove unused images/containers

# Slow performance
docker stats  # Check resource usage
docker run -m 512m --cpus=1 myapp  # Add limits

Summary Table: Essential Docker Commands

Command Purpose Example
build Create image docker build -t myapp:1.0 .
run Start container docker run -d myapp
ps List containers docker ps -a
logs View container logs docker logs -f myapp
exec Run command in container docker exec -it myapp bash
stop Stop container docker stop myapp
rm Remove container docker rm myapp
images List images docker images
push Push to registry docker push myapp:1.0
compose Manage multi-container docker-compose up

Resources