Why do inherited Docker images differ in size -


i'm lately experimenting docker. try build image architecture looking easy maintenance , extensibility.

architecture

i built images following dockerfiles , curious different container sizes. why differ much?

following base/dockerfile results in 210.9 mb image (ubuntu:trusty having 188 mb that's okay).

from ubuntu:trusty run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano env term xterm run apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

apache/dockerfile results in 224.4 mb.

from ubuntu:trusty run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano \     apache2 env term xterm run apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* copy apache2-foreground /usr/local/bin/ run chmod a+x /usr/local/bin/apache2-foreground expose 80 workdir /var/www/html cmd ["apache2-foreground"] 

apache-php/dockerfile results in 266.7 mb.

from ubuntu:trusty run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano curl \     apache2 \     libapache2-mod-php5 php5-mysql php5-mcrypt php5-gd php5-curl php-pear php-apc && \     curl -ss https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer run /usr/sbin/php5enmod mcrypt # + last 7 lines apache/dockerfile 

that's fine far haven't used inheritance until now. let's have look:

why apache-php-on-base/dockerfile result in 289.4 mb? it's same steps split in 2 images. have expected little overhead not 10 %.

from base # + apache-php/dockerfile without "install nano" 

it's bigger using multiple inheritance: apache-php-on-apache-on-base/dockerfile results in 314.9 mb.

from apache-on-base # + apache-php/dockerfile without "install nano apache2" 

where apache-on-base/dockerfile of course (resulting in 247 mb):

from base # + apache/dockerfile without "install nano" 

question: there way preventing images growing large while preserving maintainability?

update: implementing thajeztah's suggestions got following :) again!

repository          tag                 image id            created             size apache-php-on-aob   latest              2cf12a3b5872        2 minutes ago       249.9 mb apache-on-base      latest              121c8a098ff5        3 minutes ago       203.7 mb base                latest              ee95e4f8aaee        3 minutes ago       189.3 mb apache-php-on-aob   v1                  e43df5e61aed        3 days ago          314.9 mb apache-on-base      v1                  c291f91f1a10        3 days ago          247 mb base                v1                  b181fc6f181d        3 days ago          210.9 mb ubuntu              trusty              97434d46f197        10 days ago         188 mb 

without going through differences in depth, reason you're not taking layered filesystem account.

docker creates new imagelayer each instruction in dockerfile. happens (very simplified):

so, become first layer:

from ubuntu:trusty 

(and docker like)

docker build -t layer1 . 

this become second layer:

from layer1 run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano 

(and docker like)

docker build -t layer2 . 

and on.

the final image combination of images "stacked". important thing realize there file that's added in "layer1", removed in "layer2" still part of image; docker marks "removed" in layer2, doesn't make image smaller.

let's have @ first dockerfile. can see you're adding lot of files in first run instruction, add empty layer sets env var, followed run removes redundant files first run. however, files aren't removed earlier layer, still take space in final image;

from ubuntu:trusty run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano env term xterm run apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

after building (docker build -t foobar .), gives me:

repository  tag      image id      created        size foobar      latest   363aa5572838  2 minutes ago  210.9 mb 

making small change, , combine 2 run instructions, both apt-get update , apt-get clean steps take place in same run, same layer;

from ubuntu:trusty run apt-get -qq update && \     debian_frontend=noninteractive apt-get -qq install \     nano && \     apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* env term xterm 

and building that, produces image:

repository  tag      image id      created        size foobar      latest   ac8fb5e4db16  9 minutes ago  189.3 mb 

that's 20mb smaller!

you can read more in dockerfile best practice section of documentation.


Comments