DumbNewbie
DumbNewbie

Reputation: 160

Reducing Docker container size

I'm following an online tutorial on Docker. The author gave this example:

FROM busybox
RUN dd if=/dev/zero of=/tmp/test1 bs=1M count=50
RUN dd if=/dev/zero of=/tmp/test2 bs=1M count=50
docker image ls
FROM busybox
RUN dd if=/dev/zero of=/tmp/test1 bs=1M count=50
RUN dd if=/dev/zero of=/tmp/test2 bs=1M count=50
RUN rm -rf /tmp/test1
RUN rm -rf /tmp/test2
docker image ls

Why didn't the size shown get smaller with the second Dockerfile?

How would I make the second docker image ls show a smaller image, without removing the RUN dd commands?

Upvotes: 1

Views: 979

Answers (2)

Olesya Bolobova
Olesya Bolobova

Reputation: 1663

Docker, as well as container engines in general, makes use of a union mount file system concept.
Union mounting is a way of combining multiple directories into one that appears to contain their combined contents.

Thus, an image is actually composed of atomic immutable folders aka "layers".
Primary goal of this mechanism is data deduplication.
One layer may be shared by several images which saves a lot storage capacity.

E. g. you download CenOS base image (700 mb) and build several custom images on top of it.
The big CentOS part is still stored once - your images are just referencing it.

Anoher good answer - old, but still relevant.


When you build an image with Dockerfile, each separate comand in Dockerfile produces a new layer, putting it on top of the previous one (or "merging" them - in terms of union file systems).
Resulting image will contain all intermediate layers created in course of your build.

FROM busybox
# layer 1: added test1 50 mb
RUN dd if=/dev/zero of=/tmp/test1 bs=1M count=50

# layer 2: added test2 50 mb
RUN dd if=/dev/zero of=/tmp/test2 bs=1M count=50

# layer 3: "removed" test1, but actually test1 still lives in layer 1
# "removal" just made it invisible for upper layers
# that is how removal works in union mount file systems
# technically, in terms of UFS, it's not a "removal", but a "merge" of layer 3 with layer 1
RUN rm -rf /tmp/test1

# layer 4: same as layer 3
RUN rm -rf /tmp/test2

The common way to save space is to chain shell commands under a single RUN instruction.

# in this case only one layer will be created
# it will contain eventual state of the filesystem after full command chain completion
RUN dd if=/dev/zero of=/tmp/test1 bs=1M count=50 && \
    dd if=/dev/zero of=/tmp/test2 bs=1M count=50 && \
    rm -rf /tmp/test1 && \
    rm -rf /tmp/test2

Upvotes: 2

ozs
ozs

Reputation: 3681

docker share size between images. because your docker file starts the same then docker share sources between images.

run "docker system df -v" . you'll see that both image has shared size

shared size between images

by run "docker system df", you can see the reclaimable size when I build the first image

enter image description here

and after building the second docker we'll still have same size

enter image description here

in this image I changed the value 50 to 40, and you can see docker don't share between the third one to the 2 above but reclaim for new size. enter image description here

Upvotes: 1

Related Questions