design·lab

DevOps & platform

Containers & Docker

Package an app with everything it needs to run, so it behaves the same on your laptop, in CI and in production.

✗ Problem

"Works on my machine"

The app runs fine in dev but breaks in prod — because the OS, library versions and config on each machine quietly differ.

💻 Dev laptop
Node 18 · OpenSSL 3.0
deploy →
🖥️ Prod server
Node 16 · OpenSSL 1.1
The app was never packaged with its runtime, libraries or config — only the source code moved. Prod's different environment breaks it.
✓ How it works

Package app + deps + runtime into an image

A Dockerfile builds an immutable image in layers. Running it starts an isolated container — a process sharing the host's kernel (Linux namespaces + cgroups).

FROM node:18-alpine
COPY package.json .
RUN npm install     # cached layer
COPY . .
CMD ["node", "index.js"]
Dockerfile
build instructions
↓ docker build
Image
read-only layers
↓ docker run
Container
running process
Contrast with a VM: each VM ships a whole guest OS, so it's heavy and slow to boot. A container shares the host kernel, so it's just the app + its layers — light and fast.
✓ See it live

Build once, run many

docker build stacks the image layers. docker run starts containers from that same image — they share its read-only layers, each adding only a thin writable layer.

Image

FROM node:18-alpine
COPY package.json .
RUN npm install
COPY . .

Containers

Click "docker build ." to build the image.

✓ Takeaway

Images are blueprints, containers are instances

  • Immutable + portable: build once, run anywhere the same way.
  • Lightweight: shared host kernel means fast starts, no per-container guest OS.
  • Layer caching: unchanged layers (like RUN npm install) are reused across builds.
  • Image vs container: the image is the read-only blueprint; a container is a running, isolated instance of it — you can run many from one image.
  • Containers are the foundation for orchestrating many of them, at scale, with Kubernetes.