Test image is alpine, size of image is 5.58MB.
FROM alpine
RUN dd if=/dev/zero of=output1.data bs=10M count=1
RUN dd if=/dev/zero of=output2.data bs=20M count=1
RUN dd if=/dev/zero of=output3.data bs=30M count=1
RUN rm output1.data
RUN rm output2.data
RUN rm output3.data
Build command docker build -t test/v1 -f Dockerfile1 .
Results image of size 68.5 MB. Running docker history test/v1
:
IMAGE CREATED CREATED BY SIZE COMMENT
c85878093eb2 About a minute ago /bin/sh -c rm output3.data 0B
a6472cee7b45 About a minute ago /bin/sh -c rm output2.data 0B
f03d42bf0101 About a minute ago /bin/sh -c rm output1.data 0B
eee28415f103 About a minute ago /bin/sh -c dd if=/dev/zero of=output3.data b… 31.5MB
1f53010b393e About a minute ago /bin/sh -c dd if=/dev/zero of=output2.data b… 21MB
3a789b575e7a About a minute ago /bin/sh -c dd if=/dev/zero of=output1.data b… 10.5MB
389fef711851 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:ec475c2abb2d46435… 5.58MB
FROM alpine
RUN dd if=/dev/zero of=output1.data bs=10M count=1 && \
dd if=/dev/zero of=output2.data bs=20M count=1 && \
dd if=/dev/zero of=output3.data bs=30M count=1 && \
rm output1.data && \
rm output2.data && \
rm output3.data
Build command docker build -t test/v2 -f Dockerfile2 .
Results image of size 5.58 MB. Running docker history test/v2
:
IMAGE CREATED CREATED BY SIZE COMMENT
c2c78c5df4f6 About a minute ago /bin/sh -c dd if=/dev/zero of=output1.data b… 0B
389fef711851 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:ec475c2abb2d46435… 5.58MB
By running commands in a single RUN, no additional layers is created, thus size is exactly same as the original alpine image. However, image history looks horrible and caching of build steps is not working. Building is faster because no additional layers are created during build.
FROM alpine as build
RUN dd if=/dev/zero of=output1.data bs=10M count=1
RUN dd if=/dev/zero of=output2.data bs=20M count=1
RUN dd if=/dev/zero of=output3.data bs=30M count=1
RUN rm output1.data
RUN rm output2.data
RUN rm output3.data
FROM scratch
COPY --from=build / /
Build command docker build -t test/v3 -f Dockerfile3 .
Results image of size 5.58 MB. Running docker history test/v3
:
IMAGE CREATED CREATED BY SIZE COMMENT
259bb29a4f34 25 seconds ago /bin/sh -c #(nop) COPY dir:5b5e2fdf63826acb1… 5.58MB
Docker history is completely lost. The size is exactly same than with the original image.
We didn't have to touch Dockerfile
a much, just add extra build to the end of the file.
No ugly command chaining. Also, caching is working during build.
Take the Dockerfile1
, i.e.
FROM alpine
RUN dd if=/dev/zero of=output1.data bs=10M count=1
RUN dd if=/dev/zero of=output2.data bs=20M count=1
RUN dd if=/dev/zero of=output3.data bs=30M count=1
RUN rm output1.data
RUN rm output2.data
RUN rm output3.data
and let just change build command: docker build --squash -t test/v1_squashed -f Dockerfile1 .
Results 5.58 MB image which is exactly the same size than original. Cache is working. Dockerfile is looking beautiful. Even Docker history is preserved:
IMAGE CREATED CREATED BY SIZE COMMENT
bdf39f2dfa27 59 seconds ago 0B merge sha256:c85878093eb2c1ee048e4077b942b90626892ede18b3a6519587e1e2cb819faa to sha256:389fef7118515c70fd6c0e0d50bb75669942ea722ccb976507d7b087e54d5a23
<missing> 14 minutes ago /bin/sh -c rm output3.data 0B
<missing> 14 minutes ago /bin/sh -c rm output2.data 0B
<missing> 14 minutes ago /bin/sh -c rm output1.data 0B
<missing> 14 minutes ago /bin/sh -c dd if=/dev/zero of=output3.data b… 0B
<missing> 14 minutes ago /bin/sh -c dd if=/dev/zero of=output2.data b… 0B
<missing> 14 minutes ago /bin/sh -c dd if=/dev/zero of=output1.data b… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:ec475c2abb2d46435… 5.58MB