Some Dockerfile's have a lot of development inside. They need building tools, development libraries etc. The result is way to big image.
An other good reason could be security. For instance you need a personal account/key to get your source data and you don't want to leave these in your container.
Docker has a sollution for this, "Multi-Stage" builds.
The basic idea is to use the FROM directive twice (or more). The last FROM can copy files from the first one.
FROM alpine-sdk as builder
RUN build mypackage
FROM alpine
COPY --from=builder /tmp/mypackage.apk /tmp/mypackage.apk
RUN apk add --update --no-cache mypackage.apk
Result, only the needed packages are installed and there is no development trash in your container.
FROM ubuntu as private
ADD privatekey /root/.ssh/id_rsa
WORKDIR /tmp
RUN scp -i /root/.ssh/id_rsa user@host:~/myproject .
FROM ubuntu
COPY --from=private /tmp/myproject /opt
CMD ["/opt/myproject/bin/project"]
Result the final container has no private key and myproject.
In the examples before the "COPY --from" was used to copy data from the builder.
An other way to use this is to copy files from other docker images
FROM ubuntu
RUN apt update
RUN apt install nginx
COPY --from=nginx:latest /etc/nginx/nginx.conf /etc/nginx/nginx.conf
If you only want to build the builder you could do this
docker build --target builder -t myspecialbuilder