Skip to main content

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
FeatureVMContainer
OSFull guest OSShares host kernel
Boot time1–2 minutes< 1 second
Image sizeGB rangeMB range
IsolationStrongest (hypervisor)Strong (namespaces)
Performance overheadHigherNear-native
Use caseDifferent OS needs, strong isolationMicroservices, 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​

ComponentRole
Docker CLICommand-line tool you type commands into
Docker DaemonBackground service that manages containers
containerdContainer lifecycle manager (lower level than Docker)
runcOCI-compliant container runtime (actually runs processes)
RegistryRemote 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​

TagUseRisk
latestDevelopment onlyUnpredictable β€” 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​

RegistryURLNotes
Docker Hubhub.docker.comDefault, largest public registry
GitHub Container Registryghcr.ioIntegrated with GitHub Actions
Google Container Registrygcr.ioGoogle Cloud
Amazon ECR Publicpublic.ecr.awsAWS public images

Private Registries​

RegistryNotes
Amazon ECRPrivate, per AWS account
Google Artifact RegistryPrivate, replaces GCR
Azure Container RegistryPrivate, Azure
HarborSelf-hosted, open source
Nexus RepositorySelf-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​

TermDefinition
ImageImmutable, layered snapshot of a filesystem + config. Blueprint.
ContainerRunning (or stopped) instance of an image. Has writable layer.
DockerfileText file with instructions to build an image.
RegistryRemote repository for storing and distributing images.
LayerRead-only filesystem diff. Multiple layers make up an image.
TagHuman-readable label pointing to a specific image version.
DigestContent-addressable SHA256 hash β€” uniquely identifies an image.
VolumePersistent storage that survives container restarts.
NetworkVirtual network connecting containers.
Docker ComposeTool for defining multi-container apps in YAML.

Interview Questions​

  1. What is a container and how does it differ from a virtual machine?
  2. What are Docker image layers and why do they matter for build performance?
  3. What is the difference between an image and a container?
  4. Why is using the latest tag bad practice in production?
  5. What are Linux namespaces and cgroups? How do they relate to containers?
  6. What happens to data in a container's writable layer when the container is removed?
  7. What is a container registry and name three examples.
  8. Explain the Docker client-daemon architecture.