Analogy:
You bake bread → You deliver just the bread,
not the oven, flour bags, or dirty bowls.
Same thing:
Final container = just runtime + final files,
not the whole build environment.
FROM alpine:latest AS base # assigned a name in a FROM => a stage
RUN apk --no-cache add build-base
FROM base AS build1 # build upon the previous stage
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp
FROM base AS build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp
You can either build the complete image or select individual stages
# target name can specify the stages needs to be build
docker build --target base -f <dockerfile_path>