Skip to content

Commit 278f595

Browse files
Document legacy build vs BuildKit differences (docker#15477)
* Document Moby vs BuildKit differences * Apply suggestions from code review Co-authored-by: David Karlsson <[email protected]> Co-authored-by: David Karlsson <[email protected]>
1 parent 678d56c commit 278f595

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

build/building/multi-stage.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,78 @@ RUN g++ -o /binary source.cpp
205205
## Version compatibility
206206

207207
Multi-stage build syntax was introduced in Docker Engine 17.05.
208+
209+
## Differences between legacy build and BuildKit
210+
211+
The legacy Docker Engine builder processes all stages of a Dockerfile leading up to the selected `--target`. It will build a stage even if the selected target doesn't depend on that stage.
212+
213+
BuildKit only builds the stages that the target stage depends on.
214+
215+
For example, given the following Dockerfile:
216+
217+
```dockerfile
218+
# syntax=docker/dockerfile:1
219+
FROM ubuntu AS base
220+
RUN echo "base"
221+
222+
FROM base AS stage1
223+
RUN echo "stage1"
224+
225+
FROM base AS stage2
226+
RUN echo "stage2"
227+
```
228+
229+
With BuildKit enabled, building the `stage2` target in this Dockerfile means only `base` and `stage2` are processed. There is no dependency on `stage1`, so it's skipped.
230+
231+
```console
232+
$ DOCKER_BUILDKIT=1 docker build --no-cache -f Dockerfile --target stage2 .
233+
[+] Building 0.4s (7/7) FINISHED
234+
=> [internal] load build definition from Dockerfile 0.0s
235+
=> => transferring dockerfile: 36B 0.0s
236+
=> [internal] load .dockerignore 0.0s
237+
=> => transferring context: 2B 0.0s
238+
=> [internal] load metadata for docker.io/library/ubuntu:latest 0.0s
239+
=> CACHED [base 1/2] FROM docker.io/library/ubuntu 0.0s
240+
=> [base 2/2] RUN echo "base" 0.1s
241+
=> [stage2 1/1] RUN echo "stage2" 0.2s
242+
=> exporting to image 0.0s
243+
=> => exporting layers 0.0s
244+
=> => writing image sha256:f55003b607cef37614f607f0728e6fd4d113a4bf7ef12210da338c716f2cfd15 0.0s
245+
```
246+
247+
On the other hand, building the same target without BuildKit results in all stages being processed:
248+
249+
```console
250+
$ DOCKER_BUILDKIT=0 docker build --no-cache -f Dockerfile --target stage2 .
251+
Sending build context to Docker daemon 219.1kB
252+
Step 1/6 : FROM ubuntu AS base
253+
---> a7870fd478f4
254+
Step 2/6 : RUN echo "base"
255+
---> Running in e850d0e42eca
256+
base
257+
Removing intermediate container e850d0e42eca
258+
---> d9f69f23cac8
259+
Step 3/6 : FROM base AS stage1
260+
---> d9f69f23cac8
261+
Step 4/6 : RUN echo "stage1"
262+
---> Running in 758ba6c1a9a3
263+
stage1
264+
Removing intermediate container 758ba6c1a9a3
265+
---> 396baa55b8c3
266+
Step 5/6 : FROM base AS stage2
267+
---> d9f69f23cac8
268+
Step 6/6 : RUN echo "stage2"
269+
---> Running in bbc025b93175
270+
stage2
271+
Removing intermediate container bbc025b93175
272+
---> 09fc3770a9c4
273+
Successfully built 09fc3770a9c4
274+
```
275+
276+
`stage1` gets executed when BuildKit is disabled, even if `stage2` does not depend on it.
277+
278+
BuildKit is enabled by default if you use Docker Desktop.
279+
280+
Always run multi-stage builds with
281+
[BuildKit enabled](/develop/develop-images/build_enhancements/)
282+
for better performance.

0 commit comments

Comments
 (0)