Skip to content

Instantly share code, notes, and snippets.

@ahojukka5
Created January 3, 2021 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahojukka5/8c5e4c34621ebf82fd3a245c7651200d to your computer and use it in GitHub Desktop.
Save ahojukka5/8c5e4c34621ebf82fd3a245c7651200d to your computer and use it in GitHub Desktop.
Docker file sizes with different strategies

Docker file sizes

Test image is alpine, size of image is 5.58MB.

Version 1

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              

Version 2: chaining of commands

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.

Version 3: multi-stage 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.

Version 4: squashing

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              
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment