Containers vs Virtual Machines
| Virtual Machine | Container | |
|---|---|---|
| Isolation | Full OS per VM | Shared kernel, isolated process |
| Startup | Minutes | Milliseconds |
| Size | GBs | MBs |
| Density | ~10s per host | ~1000s per host |
Containers use Linux namespaces (for isolation) and cgroups (for resource limits) rather than a hypervisor.
Images and Containers
- Image — a read-only, layered filesystem snapshot. Think of it as a class.
- Container — a running instance of an image. Think of it as an object.
# Pull an image from Docker Hub
docker pull node:20-alpine
# Run a container from that image
docker run -it node:20-alpine node --version
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Stop and remove
docker stop <id>
docker rm <id>Image Layers
Each instruction in a Dockerfile creates a new layer. Layers are cached and shared:
Layer 4: COPY . . ← your source code
Layer 3: RUN npm install ← dependencies
Layer 2: COPY package*.json .
Layer 1: FROM node:20-alpine ← base image (shared with other images)
Essential Docker Commands
docker images # list local images
docker rmi node:20-alpine # remove an image
docker pull nginx:latest # pull latest nginx
docker tag myapp:latest registry/myapp:1.0 # tag for push
docker push registry/myapp:1.0 # push to registry
docker system prune -af # clean up everything unusedRegistries
A registry stores and distributes images:
- Docker Hub — public default (
docker.io) - GitHub Container Registry —
ghcr.io - AWS ECR, GCR, Azure ACR — cloud provider registries
docker login ghcr.io -u <username> --password-stdin
docker push ghcr.io/org/app:latest