docker build –target still builds only what you asked for

A multi-stage Dockerfile can serve development and production from one file, provided the build is told where to stop.

# production: everything, ending at the runtime stage
$ docker build -t app:prod .

# development: stop at the stage that still has xdebug and composer
$ docker build --target dev -t app:dev .

# and debugging a failing build: stop before the failure
$ docker build --target builder -t app:builder .
$ docker run --rm -it app:builder sh

The last form is the one worth remembering, because a build that fails in a discarded stage leaves nothing to inspect — the whole point of multi-stage is that the intermediate is thrown away. Targeting it gives you a shell in exactly the state the build was in. Under BuildKit, stages the target does not depend on are skipped entirely rather than built and discarded, which makes --target genuinely faster as well as more useful.