Docker changed the world. It took applications, wrapped them in lightweight portable containers, and made “it works on my machine” a thing of the past. Today Docker is the foundation of modern DevOps, cloud-native development, and microservices. This course covers everything — from your first docker run to orchestrating production clusters with Docker Swarm.

Table of Contents

  1. What is Docker? Why Containers?
  2. Installing Docker
  3. Docker Basics: Images, Containers, Registries
  4. Dockerfiles — Building Custom Images
  5. Volumes & Persistent Data
  6. Docker Networking
  7. Docker Compose — Multi-Container Apps
  8. Best Practices & Optimization
  9. Docker Swarm — Production Orchestration
  10. Swarm Stacks & Production Deployment
  11. Monitoring, Logging & Troubleshooting
  12. Docker Security
  13. Docker in CI/CD
  14. Advanced Docker & Real-World Patterns
  15. Complete Cheat Sheet

1. What is Docker? Why Containers?

The Problem Docker Solves

Before containers: you write code on your laptop (Node 18, Python 3.11, PostgreSQL 15). Your teammate has Node 16, Python 3.9. Your server runs Ubuntu 20.04. The production server is CentOS 7. Every environment is different. Bugs appear in production that you never saw locally. Welcome to “works on my machine.”

Enter Containers

A container packages your application with everything it needs — code, runtime, system tools, libraries, settings. It runs the same way everywhere because the environment is part of the package.

Container vs Virtual Machine

+-------------------------------------+    +-------------------------------------+
|              VM Model                |    |          Container Model            |
+-------------------------------------+    +-------------------------------------+
|   App A      |      App B           |    |  App A       |       App B          |
|  Guest OS    |     Guest OS         |    |------------  | -------------       |
|  Hypervisor                         |    |          Docker Engine             |
|  Host OS                            |    |          Host OS                   |
|  Hardware                           |    |          Hardware                  |
+-------------------------------------+    +-------------------------------------+
  • VMs: Each VM runs a full OS (GBs of overhead), boots in minutes, hardware-virtualized
  • Containers: Share the host kernel (MBs of overhead), start in milliseconds, process-level isolation
  • A single server can run hundreds of containers but only a handful of VMs

Key Benefits

  • Consistency: Same environment everywhere — dev, test, staging, production
  • Lightweight: Containers share the OS kernel, no OS overhead per app
  • Fast startup: Start in milliseconds, not minutes
  • Isolation: Each container has its own filesystem, network, processes
  • Portability: Run anywhere — laptop, server, cloud, Raspberry Pi
  • Version control: Docker images are versioned, layered, reusable
  • Microservices ready: Perfect for splitting monoliths into services
  • CI/CD friendly: Build once, deploy everywhere

2. Installing Docker

Linux (Ubuntu/Debian)

# Uninstall old versions
sudo apt remove docker docker-engine docker.io containerd runc

# Install dependencies
sudo apt update
sudo apt install ca-certificates curl gnupg

# Add Docker's official GPG key
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
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add repository
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 > /dev/null

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

# Verify
sudo docker run hello-world

# Post-install: run Docker without sudo
sudo usermod -aG docker $USER
newgrp docker

macOS

# Download Docker Desktop from:
# https://www.docker.com/products/docker-desktop/

# Or via Homebrew:
brew install --cask docker

Windows

# Enable WSL2 first:
# Run PowerShell as Admin:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
wsl --set-default-version 2

# Download Docker Desktop from docker.com

Verify Installation

docker --version
docker info
docker run hello-world

3. Docker Basics: Images, Containers, Registries

Images vs Containers

  • Image: A read-only template to create a container (like a class in OOP)
  • Container: A runnable instance of an image (like an object from a class)
  • Dockerfile: A recipe to build an image
  • Registry: A repository to store and share images (Docker Hub is default)

Working with Images

# Pull images from registry
docker pull nginx
docker pull nginx:1.25
docker pull ubuntu:22.04

# List images
docker images
docker image ls

# Inspect images
docker inspect nginx
docker history nginx

# Remove images
docker rmi nginx
docker image prune
docker image prune -a

Running Containers

# Basic run
docker run nginx
docker run -d nginx                       # Detached mode
docker run -d --name my-nginx nginx       # Give it a name
docker run -d -p 8080:80 nginx            # Port mapping
docker run -it ubuntu bash                # Interactive shell
docker run --rm alpine echo "hello"       # Auto-remove after exit
docker run --restart always nginx         # Auto-restart

# Environment variables
docker run -e DB_HOST=localhost myapp
docker run --env-file .env myapp

# Resource limits
docker run --memory="512m" --cpus="1.5" nginx

# Container lifecycle
docker start my-nginx
docker stop my-nginx
docker restart my-nginx
docker pause my-nginx
docker unpause my-nginx
docker kill my-nginx
docker rm my-nginx
docker rm -f my-nginx                     # Force remove running

# Listing
docker ps                                 # Running only
docker ps -a                              # All containers
docker ps -q                              # Quiet (IDs only)

# Logs & info
docker logs -f my-nginx
docker logs --tail 100 my-nginx
docker top my-nginx
docker stats
docker exec -it my-nginx bash
docker inspect my-nginx

Docker Hub & Registries

docker login
docker tag myapp username/myapp:v1
docker push username/myapp:v1
docker pull myregistry.com/myapp:v1

4. Dockerfiles — Building Custom Images

Dockerfile Basics

FROM ubuntu:22.04
LABEL maintainer="dev@example.com"
RUN apt update && apt install -y nginx
COPY ./index.html /var/www/html/
WORKDIR /opt/app
ENV NODE_ENV=production
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Node.js App Dockerfile

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Python App Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]

Go App (Multi-stage — 5MB image!)

FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

FROM scratch
COPY --from=builder /app/myapp /myapp
EXPOSE 8080
CMD ["/myapp"]

React + Nginx

FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80

Building Images

docker build -t myapp .
docker build -t myapp:v1.0 -t myapp:latest .
docker build -f Dockerfile.prod -t myapp .
docker build --no-cache -t myapp .
docker build --platform linux/amd64 -t myapp .

Layer Caching — Critical

# Order matters! Least-changing items first:

# BAD
COPY . .
RUN npm install          # Cache broken when ANY file changes

# GOOD
COPY package*.json ./
RUN npm install          # Cached unless dependencies change
COPY . .

5. Volumes & Persistent Data

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

# Bind Mount
docker run -v $(pwd):/app myapp

# tmpfs (in-memory)
docker run --tmpfs /app/temp myapp

# Volume commands
docker volume ls
docker volume inspect mydata
docker volume prune

# Copy data
docker cp file.txt mycontainer:/app/
docker cp mycontainer:/app/logs.log ./

6. Docker Networking

# Network types
docker network ls
# bridge, host, none, overlay

# Custom bridge network (containers resolve each other by name)
docker network create mynet
docker run -d --name db --network mynet postgres:15
docker run -d --name app --network mynet -p 3000:3000 myapp
# app can connect to db at hostname "db"

# Port mapping
docker run -p 8080:80 nginx
docker run -p 3000-3005:3000-3005 myapp

# Inspect
docker network inspect mynet

7. Docker Compose — Multi-Container Apps

# docker-compose.yml
version: "3.9"
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      DB_HOST: db
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    restart: unless-stopped

volumes:
  pgdata:

Compose Commands

docker compose up -d
docker compose down
docker compose down -v
docker compose ps
docker compose logs -f
docker compose exec web bash
docker compose build
docker compose up -d --scale web=3

8. Best Practices & Optimization

Image Size

# Use Alpine variants
FROM node:18-alpine           # ~120MB vs 350MB
FROM python:3.11-slim         # ~120MB vs 330MB

# Multi-stage builds
# Clean up in same RUN layer
RUN apt update && apt install -y build-essential   && rm -rf /var/lib/apt/lists/*

# .dockerignore
node_modules
.git
*.md
.env
__pycache__/

Security

# Never run as root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# Use specific tags (not "latest")
FROM node:18.17.1-alpine

# Read-only filesystem
docker run --read-only --tmpfs /tmp myapp

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

# Scan images
docker scout cves myapp

9. Docker Swarm — Production Orchestration

Docker Swarm turns multiple Docker hosts into a single virtual cluster. Native clustering, service discovery, load balancing, rolling updates, and self-healing.

Initialize a Swarm

# On the first manager node
docker swarm init --advertise-addr 192.168.1.10

# On worker nodes
docker swarm join --token SWMTKN-1-xxxx 192.168.1.10:2377

# Add more managers (HA)
docker swarm join-token manager

# Check status
docker node ls

Swarm Services

# Deploy
docker service create --name web --replicas 3 -p 80:80 nginx

# List
docker service ls
docker service ps web

# Scale
docker service scale web=5

# Rolling update
docker service update   --image nginx:1.25   --update-parallelism 2   --update-delay 10s   web

# Rollback
docker service rollback web

# Remove
docker service rm web

Advanced Service Options

# Global service (one per node)
docker service create --mode global --name logger fluentd

# Secrets (encrypted)
echo "supersecret" | docker secret create db_password -
docker service create --secret db_password myapp

# Placement constraints
docker service create   --constraint node.labels.env==prod   --constraint node.labels.ssd==true   --name db postgres:15

# Health checks
docker service create   --health-cmd "curl -f http://localhost/health"   --health-interval 5s   --health-retries 3   myapp

10. Swarm Stacks & Production Deployment

# docker-stack.yml
version: "3.9"
services:
  api:
    image: myapp/api
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
        delay: 10s
        order: start-first
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.api.rule=Host(\`api.example.com\`)"

  db:
    image: postgres:15-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    deploy:
      placement:
        constraints: [node.labels.ssd == true]

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

volumes:
  pgdata:
  redis_data:

secrets:
  db_password:
    external: true

Deploy & Manage Stacks

docker stack deploy -c docker-stack.yml myapp
docker stack ls
docker stack services myapp
docker stack ps myapp
docker stack rm myapp

11. Monitoring, Logging & Troubleshooting

# Real-time stats
docker stats
docker events

# Logging config
docker run --log-opt max-size=10m --log-opt max-file=3 myapp

# Health checks in Dockerfile
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD curl -f http://localhost/health || exit 1

# Troubleshooting
docker logs mycontainer
docker system df
docker system prune -a --volumes
sudo journalctl -u docker -n 100

12. Docker Security

# Runtime security
docker run --read-only --tmpfs /tmp myapp
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
docker run --security-opt=no-new-privileges:true myapp
docker run --memory="256m" --cpus="0.5" --pids-limit=100 myapp

# Docker daemon config
# /etc/docker/daemon.json:
{
  "icc": false,
  "live-restore": true,
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" },
  "storage-driver": "overlay2"
}

# DANGER: never mount docker socket unless absolutely necessary
# /var/run/docker.sock inside a container = root access to host

13. Docker in CI/CD

GitHub Actions Example

name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: \${{ github.actor }}
          password: \${{ secrets.GITHUB_TOKEN }}
      - name: Build and Push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/username/myapp:\${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      - name: Deploy to Swarm
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: \${{ secrets.SWARM_HOST }}
          script: |
            docker service update \
              --image ghcr.io/username/myapp:\${{ github.sha }} \
              --update-parallelism 2 \
              --update-delay 10s \
              myapp_api

14. Advanced Docker & Real-World Patterns

Docker BuildKit

# Enable BuildKit
export DOCKER_BUILDKIT=1

# Cache mounts
RUN --mount=type=cache,target=/var/cache/apt \
    apt update && apt install -y python3

# Secret mounts
RUN --mount=type=secret,id=token \
    TOKEN=$(cat /run/secrets/token) && ...

# SSH agent forwarding
RUN --mount=type=ssh \
    pip install git+ssh://git@github.com/private/repo.git

Graceful Shutdown Pattern

# Init process (handle zombie processes)
docker run --init myapp

# In your app, handle SIGTERM:
# process.on('SIGTERM', () => {
#   server.close(() => process.exit(0));
# });

Database Backup Pattern

# Backup
docker exec mydb pg_dump -U user mydb > backup.sql

# Backup volume
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
  tar czf /backup/pgdata-\$(date +%Y%m%d).tar.gz -C /data .

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

15. Complete Docker Cheat Sheet

Images

docker pull 
docker images
docker rmi 
docker build -t  .
docker tag  
docker push 

Containers

docker run -d --name n app
docker stop|start|restart 
docker rm -f 
docker ps -a
docker exec -it  bash
docker logs -f 
docker stats
docker inspect 

Volumes & Networks

docker volume create 
docker volume ls
docker network create 
docker network ls

Compose

docker compose up -d
docker compose down -v
docker compose logs -f
docker compose exec <service> cmd

Swarm

docker swarm init
docker swarm join --token  
docker node ls
docker service create --name s img
docker service ls
docker service scale <service>=5
docker service update --image img s
docker stack deploy -c file.yml app
docker stack ls
docker stack rm app

System

docker system df
docker system prune -a --volumes
docker system info
docker version

Conclusion

Docker has revolutionized how we build, ship, and run applications. From docker run nginx to managing production Swarm clusters with rolling updates, service discovery, and auto-healing — every step is worth learning.

Key takeaways:

  • Start small: Containerize one app, get comfortable
  • Use Docker Compose for local dev — best dev experience
  • Multi-stage builds keep images tiny (Go apps: 5MB)
  • Never run as root in containers — #1 security mistake
  • Docker Swarm is the simplest production orchestrator
  • Health checks + rolling updates = zero-downtime deploys

Next steps: Kubernetes, Docker extensions for VS Code, CI/CD pipeline, Traefik reverse proxy with auto TLS, distributed storage for stateful services (RexRay, Portworx).

Remember: Docker is not just a tool — it’s a fundamental shift in how we think about software deployment. The container way is the future.

More Free Courses on TricksPage

  • Git & GitHub Course — Master Git from basics to collaboration workflows, CI/CD, and open-source.
  • Linux Commands Course — Complete Linux command line mastery — navigation, text processing, scripting, networking.
  • Docker & Swarm Course — Containers, Dockerfiles, Compose, Swarm orchestration, and production deployment.
  • n8n Automation Course — Workflow automation with 400+ integrations, webhooks, AI, and error handling.
  • Agentic AI Course — Build AI agents with ReAct patterns, tools, memory, and multi-agent orchestration.

Leave a Reply

Your email address will not be published. Required fields are marked *