Fundamentals — Cheat Sheet
Docker · 3 topics. Download the PDF or the Instagram carousel and share it.
Cheat Sheet · AiCanCode.org
Fundamentals
Docker3 topicsQuick revision reference
1
What is Docker & Why Containers?
Docker packages an application and all its dependencies into a lightweight, portable container that runs identically on any machine — solving the classic "works on my machine" problem.
- ✓Containers share the host OS kernel; VMs have their own full OS.
- ✓An image is a read-only blueprint; a container is a running instance.
- ✓Docker layers are cached — put infrequently-changing instructions first.
- ✓Registries (Docker Hub, ECR) store and distribute images.
- ✓Docker uses Linux namespaces, cgroups, and Union FS under the hood.
Container vs VM architecture
┌──────────────────────────────────────────┠│ YOUR MACHINE │ │ │ │ ┌──────────┠┌──────────┠│ │ │ Container│ │ Container│ │ │ │ App A │ │ App B │ │ │ │ + libs │ │ + libs │ │ │ â””────┬─────┘ â””────┬─────┘ │ │ â””──────┬────────┘ │ │ Docker Engine │ │ (shared OS kernel) │ │ │ │ │ Host OS Kernel │ â””──────────────────────────────────────────┘ vs VM: ┌──────────────────────────────────────────┠│ VM 1: full Linux OS (2 GB) │ │ VM 2: full Linux OS (2 GB) │ │ Hypervisor (VMware/VirtualBox) │ │ Host OS │ â””──────────────────────────────────────────┘
2
Docker Images & Layers
Docker images are built from stacked read-only layers stored in a Union File System. Understanding layers is the key to writing efficient Dockerfiles and keeping image sizes small.
- ✓Each Dockerfile instruction creates an immutable, cached layer.
- ✓Layers are shared across images via content-addressed SHA256 hashes.
- ✓Cache invalidation: once a layer changes, all subsequent layers rebuild.
- ✓Put stable instructions (base image, dependencies) before volatile ones (source code).
- ✓Combine RUN commands and clean up in the same layer to avoid bloat.
- ✓Alpine-based images are 10-20x smaller than Debian/Ubuntu-based ones.
Docker layer stack — node app example
Layer 5 (COPY . .) ↠writable, specific to your app
Layer 4 (RUN npm ci) ↠node_modules, cached until package.json changes
Layer 3 (COPY package*.json ./) ↠package files
Layer 2 (WORKDIR /app) ↠just sets a directory pointer
Layer 1 (FROM node:20-alpine) ↠~120 MB base: Linux Alpine + Node runtime
────────────────────
All layers = final image
# Inspect layers with:
docker history my-app:latest
IMAGE CREATED SIZE COMMENT
7f2a1b3c9d4e 2 min ago 1.2MB COPY . .
<missing> 2 min ago 45.1MB RUN npm ci
<missing> 2 min ago 1.5KB COPY package*.json ./
<missing> 2 min ago 0B WORKDIR /app
<missing> 3 days ago 121MB node:20-alpine3
Writing Production-Grade Dockerfiles
Production Dockerfiles use multi-stage builds, non-root users, .dockerignore, explicit version pinning, and health checks to produce small, secure, reproducible images.
- ✓Multi-stage builds separate build environment from runtime — dramatically smaller images.
- ✓.dockerignore prevents leaking node_modules, .git, and .env files into the build context.
- ✓Never run containers as root in production — always add a non-root user.
- ✓Pin exact base image versions (node:20.15.1-alpine3.20) for reproducibility.
- ✓HEALTHCHECK lets Docker and orchestrators know if the container is actually healthy.
- ✓Never bake secrets (API keys, passwords) into Docker images — use env vars or secrets managers.
Dockerfile — multi-stage Node.js build
# ──── Stage 1: build ──────────────────────────────── FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci # includes devDependencies COPY . . RUN npm run build # compile TypeScript, bundle, etc. # ──── Stage 2: production runtime ──────────────────── FROM node:20-alpine AS runtime # fresh image — no build tools WORKDIR /app # Only copy what the app needs to run COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY package.json . # Security: run as non-root RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --retries=3 \ CMD wget -qO- http://localhost:3000/health || exit 1 CMD ["node", "dist/server.js"] # Result: # Without multi-stage: ~700 MB (includes TypeScript compiler, source maps, devDeps) # With multi-stage: ~180 MB (only runtime + dist output)
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/docker