Why does chown increase docker image size?

I can’t understand why the “chown” command should increase the size of my docker image?

The following Dockerfile creates a 5.3MB image:

FROM alpine:edge RUN adduser example -D -h /example -s /bin/sh 

In this example, however, an 8.7MB image is created:

 FROM alpine:edge RUN adduser example -D -h /example -s /bin/sh && \ chown -R example.example /lib 

Why?

Note. My actual docker file, of course, is much longer than this example, so the increase in image size is also significantly larger. That's why I don't care ..

+5
source share
3 answers

Each step in the Docker file generates a new intermediate image or “layer”, consisting of everything that has been changed in the file system from the previous layer. The docker image consists of a set of layers that are applied one on top of the other to create the final file system.

If you have:

 RUN adduser example -D -h /example -s /bin/sh 

Then you probably don't change anything except a few files in /etc ( /etc/passwd , /etc/group and their shadow equivalents).

If you have:

 RUN adduser example -D -h /example -s /bin/sh && \ chown -R example.example /lib 

Then the list of things that have been changed includes recursively everything in /lib , which is potentially larger. In fact, in my alpine:edge container, it looks like the contents of /lib is 3.4MB:

 / # du -sh /lib 3.4M /lib 

The image resizing in your example is taken into account exactly.

UPDATE

Using your actual Docker file, with the npm install ... line disabled, I don’t see the difference in the final size of the image, regardless of whether the adduser and chown commands are executed. Given:

 RUN echo "http://nl.alpinelinux.org/alpine/edge/main" > /etc/apk/repositories && \ echo "http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ apk add -U wget iojs && \ apk upgrade && \ wget -q --no-check-certificate https://ghost.org/zip/ghost-0.6.0.zip -O /tmp/ghost.zip && \ unzip -q /tmp/ghost.zip -d /ghost && \ cd /ghost && \ # npm install --production && \ sed 's/127.0.0.1/0.0.0.0/' /ghost/config.example.js > /ghost/config.js && \ sed -i 's/"iojs": "~1.2.0"/"iojs": "~1.6.4"/' package.json && \ # adduser ghost -D -h /ghost -s /bin/sh && \ # chown -R ghost.ghost * && \ npm cache clean && \ rm -rf /var/cache/apk/* /tmp/* 

I get:

 $ docker build -t sotest . [...] Successfully built 058d9f41988a $ docker inspect -f '{{.VirtualSize}}' 058d9f41988a 31783340 

Taking into account that:

 RUN echo "http://nl.alpinelinux.org/alpine/edge/main" > /etc/apk/repositories && \ echo "http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ apk add -U wget iojs && \ apk upgrade && \ wget -q --no-check-certificate https://ghost.org/zip/ghost-0.6.0.zip -O /tmp/ghost.zip && \ unzip -q /tmp/ghost.zip -d /ghost && \ cd /ghost && \ # npm install --production && \ sed 's/127.0.0.1/0.0.0.0/' /ghost/config.example.js > /ghost/config.js && \ sed -i 's/"iojs": "~1.2.0"/"iojs": "~1.6.4"/' package.json && \ adduser ghost -D -h /ghost -s /bin/sh && \ chown -R ghost.ghost * && \ npm cache clean && \ rm -rf /var/cache/apk/* /tmp/* 

I get:

 $ docker build -t sotest . [...] Successfully built 696b481c5790 $ docker inspect -f '{{.VirtualSize}}' 696b481c5790 31789262 

That is, two images have approximately the same size (the difference is about 5 KB).

I would, of course, expect the resulting image to be larger if the npm install command can work successfully (because it will install additional files).

+8
source

Now you can visually view the image and its layers using ImageLayers.io to find out why this extra size.

also, Docker History reveals similar things.

+1
source

Unfortunately, this is a known issue: https://github.com/docker/docker/issues/5505 and https://github.com/docker/docker/issues/6119#issuecomment-70606158

You can fix this by changing the docker storage driver from aufs to devicemapper, as described in https://github.com/docker/docker/issues/6119#issuecomment-268870519

0
source

All Articles