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
- What is Docker? Why Containers?
- Installing Docker
- Docker Basics: Images, Containers, Registries
- Dockerfiles — Building Custom Images
- Volumes & Persistent Data
- Docker Networking
- Docker Compose — Multi-Container Apps
- Best Practices & Optimization
- Docker Swarm — Production Orchestration
- Swarm Stacks & Production Deployment
- Monitoring, Logging & Troubleshooting
- Docker Security
- Docker in CI/CD
- Advanced Docker & Real-World Patterns
- 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 pulldocker images docker rmi docker build -t . docker tag ![]()
docker push
Containers
docker run -d --name n app docker stop|start|restartdocker rm -f docker ps -a docker exec -it bash docker logs -f docker stats docker inspect
Volumes & Networks
docker volume createdocker 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 --tokendocker 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.