Frequently Asked Question

What goes in a Dockerfile and what does each instruction do?

A Dockerfile is a text recipe that describes, line by line, how to build an image. FROM picks a base image to start from, often a minimal Linux like debian:slim, alpine, or a language image like python:3.12-slim. WORKDIR sets the working directory for subsequent instructions. COPY brings files from the build context into the image; ADD is the same but also fetches URLs and extracts archives. RUN executes a command at build time and freezes the result as a new layer. ENV sets an environment variable. EXPOSE documents which port the application listens on (it does not actually open the port). USER switches to an unprivileged account before the next instruction. CMD specifies the default command when a container starts, and ENTRYPOINT makes that command fixed with CMD becoming its default arguments.

The art is mostly about layer ordering and cache use. Each instruction's result is cached by Docker, so if you put fast-changing instructions (like COPY . .) above slow expensive ones (like RUN pip install), you invalidate the dependency layer on every code change and rebuild from scratch. The standard idiom is: copy the dependency manifest first, install dependencies, then copy the rest of the source. That way day-to-day code edits reuse the dependency layer and a build that would take three minutes from cold takes three seconds warm.

Further reading and video