What problem does Docker solve?
Imagine this scenario (which happens ALL the time):
| Situation | What you hear |
|---|---|
| Developer | "It works perfectly on my machine" |
| Production server | Error 500, crash, missing dependencies |
| New developer | "I've spent 2 days setting up the environment" |
| DevOps | "What Node version did you use? And Python?" |
Docker solves this by packaging your application WITH EVERYTHING it needs: code, runtime, libraries, configuration. If it works in Docker, it works anywhere.
🖥️ Virtual Machines vs Containers
VIRTUAL MACHINE CONTAINER (DOCKER)
─────────────── ──────────────────
┌─────────────────┐ ┌──────┐ ┌──────┐ ┌──────┐
│ App │ │ App1 │ │ App2 │ │ App3 │
├─────────────────┤ ├──────┴─┴──────┴─┴──────┤
│ Libs/Binaries │ │ Libs/Binaries │
├─────────────────┤ ├────────────────────────┤
│ Guest OS │ ← Full OS │ Docker Engine │
│ (Ubuntu 8GB) │ │ (~100MB) │
├─────────────────┤ ├────────────────────────┤
│ Hypervisor │ │ Host OS │
├─────────────────┤ ├────────────────────────┤
│ Host OS │ │ Hardware │
├─────────────────┤ └────────────────────────┘
│ Hardware │
└─────────────────┘
🐢 Heavy: 10-20 GB per VM 🚀 Light: 100-500 MB
⏱️ Boot: 1-2 minutes ⏱️ Boot: 1-2 seconds
📦 Full isolation 📦 Process-level isolation
💰 Resource savings
| Metric | Traditional VM | Docker Container |
|---|---|---|
| RAM per instance | 1-8 GB | 50-500 MB |
| Disk | 10-40 GB | 100 MB - 2 GB |
| Startup time | 30s - 2min | 1-5 seconds |
| Apps per server | 5-10 VMs | 50-100+ containers |
| CPU overhead | 15-20% | 1-5% |
💡 On a 32GB RAM server: you can run ~4 VMs or ~50 containers doing the same thing.
Why is it essential for the modern developer?
| Use | Benefit |
|---|---|
| Local development | Same environment as production |
| Onboarding | New dev productive in minutes, not days |
| CI/CD | Tests in identical environment to production |
| Microservices | Each service in its container |
| Experimenting | Try technologies without polluting your system |
| Scalability | Kubernetes orchestrates thousands of containers |
🔧 Docker alternatives
Docker popularized containers, but it's not the only option:
| Technology | Creator | Characteristics |
|---|---|---|
| Docker | Docker Inc | Most popular, Docker Hub, Docker Desktop |
| Podman | Red Hat | Daemonless, rootless, Docker CLI compatible |
| containerd | CNCF | Runtime used by Docker and Kubernetes |
| LXC/LXD | Canonical | System containers (more like VMs) |
| Colima | Open Source | Docker on macOS/Linux without Docker Desktop |
💡 Tip: If you use Linux and want to avoid Docker Desktop, Podman is the most popular alternative. Commands are almost identical:
podman runinstead ofdocker run.
Key concepts
| Concept | What it is | Analogy |
|---|---|---|
| Image | Immutable template | Written recipe |
| Container | Instance of an image | Prepared dish |
| Dockerfile | Instructions to create image | Recipe steps |
| Registry | Image repository | Recipe library |
| Volume | Persistent data | Ingredients you save |
| Network | Communication between containers | Connection between kitchens |
Installation
| System | Recommended option | Lightweight alternative |
|---|---|---|
| macOS | brew install --cask docker | Colima + Docker CLI |
| Windows | Docker Desktop (WSL2) | Podman Desktop |
| Linux | Docker Engine | Podman (daemonless) |
# Verify installation
docker --version
docker run hello-world
Container lifecycle
Dockerfile docker build Image docker run Container
────────── ─────────────────▶ ──────── ───────────────────▶ ──────────
(recipe) (frozen (served)
dish)
docker push docker pull
───────────▶ Docker Hub ◀───────────────────
(registry)
Your first container
# Test that Docker works
docker run hello-world
# Run Ubuntu interactively
docker run -it ubuntu bash
# Inside the container:
cat /etc/os-release # Ubuntu!
exit # Exit
Essential commands
# See running containers
docker ps
# See all containers
docker ps -a
# See downloaded images
docker images
# Run with interactive shell
docker run -it ubuntu bash
# Stop container
docker stop <container_id>
# Remove container
docker rm <container_id>
Practical example: Node.js
# Run Node.js 20
docker run -it node:20 node
# Now you can write JavaScript
> console.log("Hello from Docker!")
Your first Dockerfile
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "start"]
# Build image
docker build -t my-app .
# Run
docker run -p 3000:3000 my-app
Practice
→ Docker Hello World — Your first container