Dockerfile and container image size
General
As I was creating a minicontainer (minibox) (container that is based on BusyBox, but still contains everything that is needed to run as standalone without the need to use volume containers) I noticed that the resulting containers were way larger than they should have been. I only started paying attention to this as I was trying to create as small a container as possible.
After inspecting the resulting image with docker history
I noticed that the
steps that were executed while installing packages, like having the file
downloaded, unpacked using gunzip
and after that unpacked using tar
all left
a large intermediate container in the history.
I had tried to minimize the image after creation by executing rm -rf /tmp/*
but that seemed to have no effect on the resulting image size.
Solution
I tried combining all the steps needed to install a given piece of software into a single liner and that did the trick. So instead of installing Java like:
1
2
3
4
RUN wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O /tmp/jre.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jre-8u25-linux-x64.tar.gz
RUN gunzip /tmp/jre.tar.gz
RUN (cd /opt && tar xf /tmp/jre.tar)
RUN rm -rf /tmp/*
the command became:
1
RUN ( wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O /tmp/jre.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jre-8u25-linux-x64.tar.gz && gunzip /tmp/jre.tar.gz && cd /opt && tar xf /tmp/jre.tar && rm /tmp/jre.tar)
This resulted in an image of an expected size. For an image containing Java, Elasticsearch and Logstash, the reduction in size was from ~850MB to 351.1MB as compared to installing all of the applications in multiple steps.
Example
Java on BusyBox with the commands as separate steps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM progrium/busybox
MAINTAINER Ilkka Anttonen version: 0.1
# Udate wget to support SSL
RUN opkg-install wget
# Get and install Java
RUN wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O /tmp/jre.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jre-8u25-linux-x64.tar.gz
RUN gunzip /tmp/jre.tar.gz
RUN ( cd /opt && tar xf /tmp/jre.tar )
RUN rm /tmp/jre.tar
# Link Java into use, wget-ssl updates libpthread which causes Java to break
RUN ln -sf /lib/libpthread-2.18.so /lib/libpthread.so.0
RUN ln -s /opt/jre1.8.0_25/bin/java /usr/bin/java
leads to the following image:
1
2
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
sirile/testjava latest 0df3d2bce73c 3 seconds ago 407.4 MB
When inspected with docker history
it looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IMAGE CREATED CREATED BY SIZE
0df3d2bce73c About a minute ago /bin/sh -c ln -s /opt/jre1.8.0_25/bin/java /u 25 B
e143d449780d About a minute ago /bin/sh -c ln -sf /lib/libpthread-2.18.so /li 23 B
202555d24a9f About a minute ago /bin/sh -c rm /tmp/jre.tar 0 B
65f30ff37126 4 minutes ago /bin/sh -c ( cd /opt && tar xf /tmp/jre.tar ) 168.5 MB
0860f824b63b 4 minutes ago /bin/sh -c gunzip /tmp/jre.tar.gz 168.8 MB
19c2913337e8 4 minutes ago /bin/sh -c wget --no-check-certificate --no-c 62.76 MB
c655df8a63f9 24 hours ago /bin/sh -c opkg-install wget 2.565 MB
6dbf326c3ce2 29 hours ago /bin/sh -c #(nop) MAINTAINER Ilkka Anttonen v 0 B
6f114d3139e3 11 weeks ago /bin/sh -c #(nop) CMD [/bin/sh] 0 B
7acf13620725 11 weeks ago /bin/sh -c opkg-cl install http://downloads.o 461.1 kB
7fff0c6f0b8d 11 weeks ago /bin/sh -c opkg-cl install http://downloads.o 69.19 kB
8db8f013bfca 11 weeks ago /bin/sh -c #(nop) ADD file:c63e5d6cb74e15cf63 9.15 kB
bbd692fe2ca1 11 weeks ago /bin/sh -c #(nop) ADD file:3bae78d4720418c677 103 B
21082221cb6e 11 weeks ago /bin/sh -c #(nop) ADD file:393caa32e4f0f6eef6 220 B
015fb409be0d 11 weeks ago /bin/sh -c #(nop) ADD file:2052bcafea75adbdd2 4.268 MB
e2fb46397934 11 weeks ago /bin/sh -c #(nop) MAINTAINER Jeff Lindsay <pr 0 B
511136ea3c5a 18 months ago 0 B
After modifying the Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
FROM progrium/busybox
MAINTAINER Ilkka Anttonen version: 0.1
# Udate wget to support SSL
RUN opkg-install wget
# Get and install Java
RUN ( wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O /tmp/jre.tar.gz http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jre-8u25-linux-x64.tar.gz && gunzip /tmp/jre.tar.gz && cd /opt && tar xf /tmp/jre.tar && rm /tmp/jre.tar )
# Link Java into use, wget-ssl updates libpthread which causes Java to break
RUN ln -sf /lib/libpthread-2.18.so /lib/libpthread.so.0
RUN ln -s /opt/jre1.8.0_25/bin/java /usr/bin/java
the resulting image is
1
2
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
sirile/testjava latest 5e0d93d4a5c0 24 hours ago 175.9 MB
and when inspected with docker history
it looks like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
IMAGE CREATED CREATED BY SIZE
5e0d93d4a5c0 24 hours ago /bin/sh -c ln -s /opt/jre1.8.0_25/bin/java /u 25 B
3d1c972185dd 24 hours ago /bin/sh -c ln -sf /lib/libpthread-2.18.so /li 23 B
01f2e42fda1e 24 hours ago /bin/sh -c ( wget --no-check-certificate --no 168.5 MB
c655df8a63f9 24 hours ago /bin/sh -c opkg-install wget 2.565 MB
6dbf326c3ce2 30 hours ago /bin/sh -c #(nop) MAINTAINER Ilkka Anttonen v 0 B
6f114d3139e3 11 weeks ago /bin/sh -c #(nop) CMD [/bin/sh] 0 B
7acf13620725 11 weeks ago /bin/sh -c opkg-cl install http://downloads.o 461.1 kB
7fff0c6f0b8d 11 weeks ago /bin/sh -c opkg-cl install http://downloads.o 69.19 kB
8db8f013bfca 11 weeks ago /bin/sh -c #(nop) ADD file:c63e5d6cb74e15cf63 9.15 kB
bbd692fe2ca1 11 weeks ago /bin/sh -c #(nop) ADD file:3bae78d4720418c677 103 B
21082221cb6e 11 weeks ago /bin/sh -c #(nop) ADD file:393caa32e4f0f6eef6 220 B
015fb409be0d 11 weeks ago /bin/sh -c #(nop) ADD file:2052bcafea75adbdd2 4.268 MB
e2fb46397934 11 weeks ago /bin/sh -c #(nop) MAINTAINER Jeff Lindsay <pr 0 B
511136ea3c5a 18 months ago 0 B
Conclusion
Combining the steps that would otherwise leave behing a temporary file or folder is recommended as otherwise the intermediary containers created during the build are still retained as part of the end image.