# Dockerfile and Image Build ## A Dockerfile is a recipe for an image Every image you've used so far (`nginx:alpine`, `alpine:3.19`) was itself BUILT from a Dockerfile by someone else. This module teaches you to write your own. ## The core instructions - **`FROM `** — every Dockerfile starts by choosing a base image to build on top of. Almost nothing is built completely from scratch. - **`WORKDIR `** — sets the working directory for every instruction that follows it (and for the container's default working directory when it runs). - **`COPY `** — copies files from your BUILD CONTEXT (the directory you run `docker build` from) into the image. - **`RUN `** — executes a command DURING the build, creating a new layer with its result (installing a package, for example). - **`CMD `** (conceptually) — sets the DEFAULT command a container runs when started from this image, if nothing else is specified. - **`ENTRYPOINT `** (conceptually) — similar to `CMD`, but harder to override at `docker run` time — the two are often combined (`ENTRYPOINT` as the fixed program, `CMD` as its default arguments). ## Build context and `.dockerignore` `docker build -t mytag .` — that final `.` is the **build context**: the directory Docker can see and copy files FROM during the build. A `.dockerignore` file (same idea as `.gitignore` from ROOT 03) excludes files from the build context — keeping large or irrelevant files (like a local `.git` folder or dependency caches) out of your image and speeding up builds. ## Layers, again Each instruction in a Dockerfile creates one layer, cached individually. Docker reuses cached layers for instructions that haven't changed since the last build — which is why the ORDER of instructions matters for build speed: put things that change rarely (like `FROM` and installing dependencies) before things that change often (like copying your actual application code), so a small code change doesn't invalidate expensive earlier layers. ## Instructor Notes **Lesson goal:** Give students enough Dockerfile literacy to write a real, small, working image — not exhaustive coverage of every possible instruction. **Approximate timing:** 18 minutes read; 10 minutes live. **Common misconception to watch for:** copying application code before installing dependencies — reinforce the "changes-rarely-first" layer-ordering principle with a concrete example. **Demo idea:** build the same Dockerfile twice with no changes, showing the second build using fully cached layers (`CACHED` in the output) and finishing almost instantly.