Introduction to Docker
Introduction to Docker
Docker has revolutionized how developers build, ship, and run applications. Before diving into commands and configurations, it's essential to understand what containers are, how they differ from virtual machines, and why Docker became the dominant containerization platform.
What Is a Container?
A container is a lightweight, standalone, executable package that includes everything needed to run a piece of software: code, runtime, system tools, libraries, and settings. Containers isolate software from its environment, ensuring consistent behavior across different computing environments.
Note
Think of a container as a shipping container for software. Just like physical shipping containers standardized global trade by providing a consistent way to transport goods, software containers standardize application deployment.
The Problem Docker Solves
"It Works on My Machine"
Before containers, developers faced a common frustration: code that worked perfectly on their development machine would fail in staging or production. This happened because environments differed in:
- Operating system versions
- Library versions and dependencies
- Configuration settings
- Runtime environments
# The classic developer excuse
"But it works on my machine!"Environment Inconsistency
Consider a Node.js application that requires:
- Node.js 20.x
- npm packages with specific versions
- Environment variables for configuration
- System libraries like ImageMagick
Getting all of this exactly right across development, staging, and production machines was error-prone and time-consuming.
Traditional Deployment Challenges
| Environment | Node Version | npm Version | ImageMagick | Result |
|---|---|---|---|---|
| Developer A | 20.11.0 | 10.2.4 | 7.1.1 | ✅ Works |
| Developer B | 18.19.0 | 9.8.1 | 7.0.0 | ❌ Fails |
| Staging | 20.10.0 | 10.2.3 | Not installed | ❌ Fails |
| Production | 20.11.0 | 10.2.4 | 6.9.12 | ⚠️ Partial |
Docker solves this by packaging the application with its environment, guaranteeing identical behavior everywhere.
Containers vs Virtual Machines
While both containers and virtual machines (VMs) provide isolation, they work fundamentally differently.
Virtual Machines
VMs run a complete operating system on top of a hypervisor. Each VM includes:
- Full guest operating system (GB of storage)
- Virtualized hardware
- Complete system resources allocation
┌─────────────────────────────────────────────────────────┐
│ Host Operating System │
├─────────────────────────────────────────────────────────┤
│ Hypervisor │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ VM 1 │ VM 2 │ VM 3 │ VM 4 │
│ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │
│ │ App A │ │ │ App B │ │ │ App C │ │ │ App D │ │
│ └───────┘ │ └───────┘ │ └───────┘ │ └───────┘ │
│ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │
│ │ Bins/ │ │ │ Bins/ │ │ │ Bins/ │ │ │ Bins/ │ │
│ │ Libs │ │ │ Libs │ │ │ Libs │ │ │ Libs │ │
│ └───────┘ │ └───────┘ │ └───────┘ │ └───────┘ │
│ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │
│ │Guest │ │ │Guest │ │ │Guest │ │ │Guest │ │
│ │ OS │ │ │ OS │ │ │ OS │ │ │ OS │ │
│ └───────┘ │ └───────┘ │ └───────┘ │ └───────┘ │
└─────────────┴─────────────┴─────────────┴───────────────┘Containers
Containers share the host OS kernel and run as isolated processes. They include:
- Only the application and its dependencies
- Minimal filesystem layers (MB instead of GB)
- Shared kernel resources
┌─────────────────────────────────────────────────────────┐
│ Host Operating System │
├─────────────────────────────────────────────────────────┤
│ Docker Engine │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ Container 1 │ Container 2 │ Container 3 │ Container 4 │
│ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │
│ │ App A │ │ │ App B │ │ │ App C │ │ │ App D │ │
│ └───────┘ │ └───────┘ │ └───────┘ │ └───────┘ │
│ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │ ┌───────┐ │
│ │ Bins/ │ │ │ Bins/ │ │ │ Bins/ │ │ │ Bins/ │ │
│ │ Libs │ │ │ Libs │ │ │ Libs │ │ │ Libs │ │
│ └───────┘ │ └───────┘ │ └───────┘ │ └───────┘ │
└─────────────┴─────────────┴─────────────┴───────────────┘Containers vs VMs Comparison
| Characteristic | Virtual Machine | Container |
|---|---|---|
| Size | Gigabytes | Megabytes |
| Startup Time | Minutes | Seconds |
| Performance | Overhead from hypervisor | Near-native |
| Isolation | Strong (hardware-level) | Process-level |
| OS Flexibility | Any OS | Same kernel family |
| Resource Usage | Higher | Lower |
| Density | Tens per host | Hundreds per host |
Docker Architecture
Docker uses a client-server architecture with several key components:
Docker Daemon (dockerd)
The Docker daemon runs on the host machine and manages Docker objects:
- Images
- Containers
- Networks
- Volumes
# The daemon listens for Docker API requests
# Usually runs as a background service
sudo systemctl status dockerDocker Client (docker)
The Docker client is the primary way users interact with Docker. When you run commands like docker run, the client sends them to the daemon:
# The client communicates with the daemon via REST API
docker run hello-worldDocker Registry
Registries store Docker images. Docker Hub is the default public registry, but you can run private registries:
# Pulling an image from Docker Hub
docker pull nginx:latest
# Pulling from a private registry
docker pull myregistry.example.com/myapp:1.0Docker Objects
Docker manages several types of objects:
Images: Read-only templates used to create containers. Images are built in layers, where each layer represents a set of filesystem changes.
Containers: Runnable instances of images. You can create, start, stop, move, or delete containers using the Docker API or CLI.
Networks: Enable containers to communicate with each other and the outside world.
Volumes: Persist data generated by containers.
Warning
Containers are ephemeral by default. When a container is deleted, any data stored inside it is lost. Always use volumes for data that needs to persist.
The Container Lifecycle
Understanding the container lifecycle is crucial for working effectively with Docker:
┌─────────┐ create ┌─────────┐ start ┌─────────┐
│ Image │ ─────────▶ │ Created │ ─────────▶│ Running │
└─────────┘ └─────────┘ └────┬────┘
│
┌─────────────────────────────┤
│ stop │ pause
▼ ▼
┌─────────┐ ┌──────────┐
│ Stopped │ │ Paused │
└────┬────┘ └──────────┘
│ remove
▼
┌─────────┐
│ Deleted │
└─────────┘Container States
| State | Description |
|---|---|
| Created | Container exists but hasn't been started |
| Running | Container is executing with an active process |
| Paused | Container processes are suspended |
| Stopped | Container has exited (process completed/killed) |
| Deleted | Container has been removed from the system |
Why Docker for Development?
Docker offers several compelling benefits for developers:
Reproducible Environments
# This Dockerfile defines exactly what your app needs
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "start"]Every developer, CI server, and production environment uses the same image.
Isolation
Run multiple projects with different (even conflicting) dependencies simultaneously:
# Project A needs Node 18
docker run -d --name project-a node:18-alpine tail -f /dev/null
# Project B needs Node 20
docker run -d --name project-b node:20-alpine tail -f /dev/null
# Both coexist happily on the same machineMicroservices Architecture
Docker makes it practical to decompose applications into services:
# docker-compose.yml
services:
frontend:
image: myapp-frontend:1.0
api:
image: myapp-api:1.0
database:
image: postgres:16
cache:
image: redis:7Quick Onboarding
New team members can get a development environment running in minutes instead of hours or days:
# Instead of a 10-page setup document...
git clone https://github.com/company/project.git
cd project
docker compose up
# Done! The entire stack is running.Docker Ecosystem
Docker has a rich ecosystem of tools and services:
Docker Desktop
A desktop application for Mac and Windows that includes:
- Docker Engine
- Docker CLI
- Docker Compose
- Kubernetes
- GUI for managing containers
Docker Hub
The default public registry with millions of images:
- Official images maintained by Docker and vendors
- Community images contributed by developers
- Automated builds from GitHub repositories
Docker Compose
A tool for defining multi-container applications:
# Start all services defined in docker-compose.yml
docker compose up -d
# View running services
docker compose ps
# Stop everything
docker compose downContainer Orchestration
For production deployments at scale:
- Kubernetes: The industry-standard orchestrator
- Docker Swarm: Docker's native clustering solution
- Amazon ECS: AWS's container service
- Azure Container Apps: Microsoft's serverless container platform
Note
While this guide focuses on Docker, the skills you learn here transfer directly to Kubernetes and other orchestrators—they all run containers built with Docker.
What You'll Learn
This guide covers the complete Docker development workflow:
- Getting Started: Installing Docker and running your first containers
- Images: Building and managing Docker images
- Dockerfile Mastery: Writing efficient, secure Dockerfiles
- Networking: Connecting containers and exposing services
- Data Persistence: Managing volumes and persistent storage
- Docker Compose: Orchestrating multi-container applications
- Development Workflows: Hot reloading, debugging, and productivity
- Security: Best practices for secure containers
- Production: Deploying containers in production environments
- CI/CD: Integrating Docker into your development pipeline
By the end, you'll have the skills to containerize any application and run it confidently from development to production.