The recipe that defines exactly how an image gets built, instruction by instruction.
Instructions run in order, each generally producing a layer. RUN executes at build time and bakes its result into a layer, while CMD and ENTRYPOINT define what actually runs when a container starts, not during the build. The common point of confusion is overridability: CMD is easily overridden by arguments passed to docker run, while ENTRYPOINT generally isn't unless explicitly overridden with a flag — and the two are often combined, with ENTRYPOINT defining the fixed command and CMD supplying its default arguments.
COPY and ADD look interchangeable but aren't: ADD has extra built-in behavior (fetching from a remote URL, auto-extracting local tar archives) that makes it less predictable, which is exactly why COPY is generally preferred for straightforward file copying. .dockerignore keeps the build context small and cache-friendly by excluding files that shouldn't be sent to the build at all. And a subtle but important detail: deleting a file in a later RUN instruction doesn't shrink the image, since the earlier layer where that file was created already baked its size into the image history — cleanup has to happen in the same layer that created the file to actually matter.
What you'll walk away knowing