StudyToCert

All certifications / CKAD / Lessons

Certified Kubernetes Application Developer CKAD (Kubernetes v1.35 curriculum) · Domain 1: Application Design and Build

Writing Dockerfiles: base images, layers, multi-stage builds, ENTRYPOINT vs CMD

▶ Watch the overview video

Last reviewed September 25, 2026 · Leer en español

A container image is a packaged filesystem plus metadata that says how to start your application. A Dockerfile is the recipe for building it: a text file of instructions that the builder runs top to bottom. The CKAD exam expects you to read, fix and write short Dockerfiles, so you need to know what each common instruction does and how the result is stored.

Every Dockerfile starts from a base image with FROM, for example FROM python:3.12-slim or FROM alpine. The base supplies the operating system files and often a language runtime. Smaller bases such as slim, alpine or distroless images mean faster pulls and fewer packages that could contain vulnerabilities. After FROM you typically use WORKDIR to set the working directory, COPY to bring in source files, RUN to execute build commands such as installing dependencies, ENV to set environment variables, EXPOSE to document a listening port and USER to switch away from root.

Instructions that change the filesystem (mainly RUN, COPY and ADD) each create a new read-only layer. Layers are cached: if an instruction and everything before it are unchanged, the builder reuses the cached layer instead of running it again. That is why you copy the dependency manifest (such as requirements.txt or package.json) and install dependencies before copying the rest of your source code. Editing a source file then only invalidates the later layers, and rebuilds are fast. Deleting a file in a later layer does not shrink the image, because the earlier layer still contains it.

A multi-stage build uses more than one FROM in the same file. The first stage has compilers and build tools; the final stage starts from a small runtime image and copies only the finished artifact with COPY --from=build. Build tools never reach the image you ship, which makes it smaller and reduces its attack surface.

FROM golang:1.22 AS build
WORKDIR /src
COPY go.mod ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app

FROM alpine
COPY --from=build /app /app
USER 1000
ENTRYPOINT ["/app"]
CMD ["--port", "8080"]

ENTRYPOINT and CMD together define the start command. ENTRYPOINT is the executable that always runs; CMD supplies default arguments that are easy to override. When both are present, the container runs ENTRYPOINT followed by CMD, so the example above runs /app --port 8080. If you run the image with extra arguments, they replace CMD but keep ENTRYPOINT. If only CMD is set, it is the whole command and any arguments you pass replace it entirely.

Prefer the exec form, a JSON array like ["/app"], over the shell form ENTRYPOINT /app. The exec form runs your program directly as process 1, so it receives signals such as SIGTERM when Kubernetes stops the Pod. The shell form wraps it in /bin/sh -c, and the shell may not forward signals, leading to slow, forced shutdowns.

Key terms

Base image
The image named in FROM that supplies the starting filesystem and runtime for your build.
Layer
A cached, read-only filesystem change produced by an instruction such as RUN or COPY.
Multi-stage build
A Dockerfile with several FROM stages where only selected artifacts are copied into the final image.
ENTRYPOINT
The fixed executable the container runs at start.
CMD
Default arguments (or a default command if there is no ENTRYPOINT) that are replaced by arguments given at run time.
Real-world example

A team's Python image took four minutes to rebuild after every code change. They moved COPY requirements.txt . and RUN pip install -r requirements.txt above COPY . ., so the dependency layer stayed cached, and rebuilds dropped to seconds. Switching to a multi-stage build also cut the final image size by more than half.

Exam tip: Remember the combination rule: ENTRYPOINT plus CMD run together, run-time arguments replace only CMD. Questions often ask what command a container actually runs.

Check yourself

Why should you copy the dependency file and install packages before copying the rest of the source?

Because layers are cached in order; code changes then invalidate only the later layers, so the slow dependency install is reused from cache.

An image has ENTRYPOINT ["ping"] and CMD ["localhost"]. What runs if you start it with the argument example.com?

ping example.com, because run-time arguments replace CMD while ENTRYPOINT stays.

What does a multi-stage build achieve?

It keeps build tools and intermediate files out of the final image, making it smaller and reducing attack surface.

Study CKAD for free
A week-by-week plan with every lesson, quizzes, checkpoint tests, a practice exam and hands-on labs.
Open the CKAD study plan