I have heard the number is not equal to all sizes of layers adding together inside an image. And it is also not the size of disk space it occupies.
Now I want to check the logic by source code (in this repo: https://github.com/docker/docker-ce), because seeing is believing! But after navigating the code for a lot of time, I found that I was not able to find the real imag-size-computing code.
So which function/file is the docker used to perform the size logic?
Before digging too deep, you may find it useful to understand how Linux implements the overlay filesystem. I include a bit on this the first exercise of my intro presentation's build section. The demo notes include each of the commands I'm running and it gives you an idea of how layers are merged, and what happens when you add/modify/delete from a layer.
This is implementation dependent, based on your host OS and the graph driver being used. I'm taking the example of a Linux OS and Overlay2 since that's the most common use case.
It starts by looking at the image layer storage size:
In there is a call to
layerStoreswhich itself is a mapping to layer.Store:Digging into the
layer.Storeimplementation forGetRWLayer, there is the following definition:Following that to find the
Sizeimplementation for the mount reference, there is this function that gets into the specific graph driver:Looking at the overlay2 graph driver to find the DiffSize function:
That is calling
naiveDiffwhich implements Size in the graphDriver package:Following
archive.ChangeSizewe can see this implementation:At which point we are using
os.Lstatto return a struct that includesSizeon each entry that is an add or modify to each directory. Note that this is one of several possible paths the code takes, but I believe it's one of the more common ones for this scenario.