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.