Skip to content

Images & the Dockerfile — Module Overview

A Docker image is a read-only package that contains everything needed to run a program — the OS filesystem, runtime, libraries, application code, and default configuration. Think of it as a recipe: the recipe itself never changes, but you can bake as many cakes (containers) from it as you like.

Images are built from stacked, read-only layers. Each layer represents a change — a file added, a package installed, a configuration written. When you stack layers on top of each other you get a complete filesystem, but Docker only stores (and transfers) the layers that have changed, keeping images lean.

flowchart TB
  img["Image (read-only)"]
  l3["Layer 3: COPY app/ /app/ (your code)"]
  l2["Layer 2: RUN npm install (dependencies)"]
  l1["Layer 1: FROM node:22-alpine (base OS + runtime)"]
  img --> l3 --> l2 --> l1
An image is a stack of read-only layers

A running container is an image with one extra writable layer on top. The image is untouched — the container writes to its own scratch layer. Stop the container and that layer disappears (unless you save it).

flowchart TB
  con["Container (running)"]
  w["Writable layer (container-specific changes, deleted on stop)"]
  l3["Layer 3 (read-only)"]
  l2["Layer 2 (read-only)"]
  l1["Layer 1 (read-only)"]
  con --> w --> l3 --> l2 --> l1
A container adds a writable layer on top of the image

A Dockerfile is a plain-text file of instructions that tells Docker how to build an image. Each instruction becomes a layer. You run docker build to turn a Dockerfile into an image, and docker run to start a container from that image.

Here is the simplest possible Dockerfile:

# syntax=docker/dockerfile:1
FROM alpine:3.20
CMD ["echo", "Hello, Docker!"]

Build and run it:

Terminal window
docker build -t hello .
docker run --rm hello

Expected output:

Hello, Docker!
LessonWhat you will learn
This pageImages vs containers, layers, first build
Dockerfile basicsCore instructions: FROM, WORKDIR, COPY, RUN, ENV, EXPOSE
Build & tagBuild context, -t name:tag, docker images, .dockerignore
Layers & cacheHow build cache works, instruction ordering for speed
CMD vs ENTRYPOINTExec form, shell form, default arguments, overrides

Paste the snippet below into a Play with Docker session, run the two commands, and see Docker build a tiny image from scratch.

# syntax=docker/dockerfile:1
FROM alpine:3.20
CMD ["echo", "Hello, Docker!"]
# --- build & run ---
# docker build -t hello .
# docker run --rm hello
What is a Docker image?
What happens to a container's writable layer when the container stops?
Which command turns a Dockerfile into an image?