Docker Fundamentals
What is a Container?β
A container is a lightweight, isolated process that packages an application with everything it needs to run β code, runtime, libraries, and config β so it behaves identically everywhere.
Without containers: With containers:
Your App βββββββββββββββββββ
β depends on β Your App β
Java 17 β Java 17 β β All bundled
Spring Boot 3.x β Spring Boot 3.x β inside image
libssl 1.1 β libssl 1.1 β
β must match βββββββββββββββββββ
The host OS Runs on any host
β often it doesn't
Containers vs Virtual Machinesβ
Virtual Machine Container
ββββββββββββββββββββββββ ββββββββββββββββββββββββ
β App A β β App A β App B β
ββββββββββββββββββββββββ€ ββββββββββββΌβββββββββββββ€
β Guest OS (Linux) β β Libs β Libs β
ββββββββββββββββββββββββ€ ββββββββββββ΄βββββββββββββ€
β Hypervisor β β Container Runtime β
ββββββββββββββββββββββββ€ β (Docker Engine) β
β Host OS β βββββββββββββββββββββββββ€
ββββββββββββββββββββββββ€ β Host OS (Linux) β
β Hardware β βββββββββββββββββββββββββ€
ββββββββββββββββββββββββ β Hardware β
βββββββββββββββββββββββββ
Size: GBs Size: MBs
Boot: Minutes Boot: Milliseconds
Isolation: Full OS boundary Isolation: Linux namespaces + cgroups
| Feature | VM | Container |
|---|---|---|
| OS | Full guest OS | Shares host kernel |
| Boot time | 1β2 minutes | < 1 second |
| Image size | GB range | MB range |
| Isolation | Strongest (hypervisor) | Strong (namespaces) |
| Performance overhead | Higher | Near-native |
| Use case | Different OS needs, strong isolation | Microservices, fast scaling |
Containers use Linux namespaces (isolate processes, filesystem, network) and cgroups (limit CPU, memory) β not a separate OS kernel.
Docker Architectureβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Docker Client (CLI) β
β docker build Β· docker run Β· docker push β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β REST API (unix socket / TCP)
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β Docker Daemon (dockerd) β
β ββββββββββββββ βββββββββββββββ ββββββββββββββββββββββ β
β β Images β β Containers β β Networks/Volumes β β
β ββββββββββββββ βββββββββββββββ ββββββββββββββββββββββ β
β Uses: containerd β runc (OCI runtime) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β pull/push
ββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β Registry (Docker Hub / ECR / GCR / Nexus) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Componentsβ
| Component | Role |
|---|---|
| Docker CLI | Command-line tool you type commands into |
| Docker Daemon | Background service that manages containers |
| containerd | Container lifecycle manager (lower level than Docker) |
| runc | OCI-compliant container runtime (actually runs processes) |
| Registry | Remote store for Docker images |
Images and Layersβ
An image is built from read-only layers stacked on top of each other.
FROM eclipse-temurin:21-jre-alpine β Layer 1: Base OS + JRE
RUN apk add curl β Layer 2: Add curl package
COPY app.jar /app/app.jar β Layer 3: Your application JAR
Layer 3: app.jar β changes most often (yours)
Layer 2: curl installed β changes occasionally
Layer 1: JRE Alpine β changes rarely (base)
Why Layers Matterβ
- Caching: If Layer 1 and 2 haven't changed, Docker reuses them from cache β only Layer 3 is rebuilt. Dramatically speeds up builds.
- Sharing: Multiple images sharing the same base layer only store it once on disk.
- Immutability: Layers are read-only. Running a container adds a thin writable layer on top β the image itself is never modified.
Running container:
βββββββββββββββββββββββββββββββ
β Writable layer (container) β β temporary, lost when container removed
βββββββββββββββββββββββββββββββ€
β Layer 3: app.jar β read-only
βββββββββββββββββββββββββββββββ€
β Layer 2: curl β read-only
βββββββββββββββββββββββββββββββ€
β Layer 1: JRE Alpine β read-only
βββββββββββββββββββββββββββββββ
Image Naming and Tagsβ
docker.io / library / ubuntu : 24.04
β β β β
Registry Namespace Image Tag/version
# Examples:
ubuntu # docker.io/library/ubuntu:latest
nginx:1.25 # docker.io/library/nginx:1.25
mycompany/myapp:1.0.0 # docker.io/mycompany/myapp:1.0.0
123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:v2 # AWS ECR
Tag Best Practicesβ
| Tag | Use | Risk |
|---|---|---|
latest | Development only | Unpredictable β changes silently |
1.0.0 (semver) | Production β | Immutable reference |
sha256:abc123... | Pinned exact version β | Most explicit, never changes |
# Always tag with version + latest for production images
docker build -t myapp:1.2.3 -t myapp:latest .
# Pull by digest (guaranteed immutable)
docker pull ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
Container Lifecycleβ
docker create
Image βββββββββββββββββββ Created
β
docker start β
β
Running βββββ docker restart
β
docker pause β
Paused
β
docker unpause β
Running
β
docker stop (SIGTERM) β
docker kill (SIGKILL) β
Stopped/Exited
β
docker rm β
Removed (deleted)
Shortcut: docker run = docker create + docker start
Registriesβ
Public Registriesβ
| Registry | URL | Notes |
|---|---|---|
| Docker Hub | hub.docker.com | Default, largest public registry |
| GitHub Container Registry | ghcr.io | Integrated with GitHub Actions |
| Google Container Registry | gcr.io | Google Cloud |
| Amazon ECR Public | public.ecr.aws | AWS public images |
Private Registriesβ
| Registry | Notes |
|---|---|
| Amazon ECR | Private, per AWS account |
| Google Artifact Registry | Private, replaces GCR |
| Azure Container Registry | Private, Azure |
| Harbor | Self-hosted, open source |
| Nexus Repository | Self-hosted, enterprise |
# Login to Docker Hub
docker login
# Login to AWS ECR
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Tag for ECR
docker tag myapp:1.0.0 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:1.0.0
# Push
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:1.0.0
Key Concepts Summaryβ
| Term | Definition |
|---|---|
| Image | Immutable, layered snapshot of a filesystem + config. Blueprint. |
| Container | Running (or stopped) instance of an image. Has writable layer. |
| Dockerfile | Text file with instructions to build an image. |
| Registry | Remote repository for storing and distributing images. |
| Layer | Read-only filesystem diff. Multiple layers make up an image. |
| Tag | Human-readable label pointing to a specific image version. |
| Digest | Content-addressable SHA256 hash β uniquely identifies an image. |
| Volume | Persistent storage that survives container restarts. |
| Network | Virtual network connecting containers. |
| Docker Compose | Tool for defining multi-container apps in YAML. |
Interview Questionsβ
- What is a container and how does it differ from a virtual machine?
- What are Docker image layers and why do they matter for build performance?
- What is the difference between an image and a container?
- Why is using the
latesttag bad practice in production? - What are Linux namespaces and cgroups? How do they relate to containers?
- What happens to data in a container's writable layer when the container is removed?
- What is a container registry and name three examples.
- Explain the Docker client-daemon architecture.