6

When I list my Docker images, I can see their sizes:

$ sudo docker image ls

REPOSITORY TAG IMAGE ID CREATED SIZE travisci/ci-ubuntu-1804 packer-1606831264-7957c7a9 0a7a71407638 8 days ago 15.6GB travisci/ci-ubuntu-1804 packer-1593521720-ca42795e 6093ba41f031 5 months ago 12.3GB travisci/ci-sardonyx packer-1547455648-2c98a19 d1b323af5b2a 23 months ago 9.02GB

However, docker containers do not display the space used:

$ sudo docker container ls

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5794ae898b68 6093ba41f031 "/sbin/init" 10 minutes ago Up 10 minutes travis 762e3f8df2da 0a7a71407638 "/sbin/init" 4 hours ago Up 4 hours distracted_noyce

Of course, I understand that if you're writing to containers, some space will be used on the hard drive.

But when you create a container, does Docker actually clone the image before booting up the container? Or does it work with diffs, only storing the differences between the image and the current container disk state?

And, how can I see the actual disk space used by a container?

BenMorel
  • 198
  • 1
  • 8

3 Answers3

12

Yes, docker containers when they are running can take up some space as per your workload and application but as mentioned in the other answers - containers are built over layered filesystem therefore only extra space they consume is from some file/object they create/download during runtime which is not the part of base image like some debug log files, etc.

For ex. - When you run 100 containers of a base image of size 1GB, docker will not consume 100 GB of disk space as it leverages layered filesystem and top immutable layer is shared across all containers of same image.

When you stop and remove (yes!, remove explicitly or use --rm flag with docker run command) a container then it's space is reclaimed.

To check space used by containers (and other objects), you can use:

$ docker system df and for detailed info. use verbose flag $ docker system df -v

Initially when you start a container the SIZE column will show 0B but as soon as you start writing to the disk SIZE will change.

EDIT: added more info. as suggested by @Benjamin in comments

Oli
  • 293
  • 2
  • 9
  • Thank you; is there a way I can see the actual disk space used by each container, on top of immutable layers? – BenMorel Dec 13 '20 at 16:44
  • 1
    try docker system df -v. For more see - https://docs.docker.com/engine/reference/commandline/system_df/ – Oli Dec 13 '20 at 16:48
  • docker system df -v does output the actual disk space used by a container, in the SIZE column. It's indeed 0 bytes when I start the container, then starts showing a non-zero size as soon as I start writing to disk. You should probably add that to your answer! – BenMorel Dec 13 '20 at 20:53
  • Thanks! @Benjamin will do. – Oli Dec 15 '20 at 04:28
  • When you run 100 containers of a base image of size 1GB how much space would they consume? – alper Jul 01 '22 at 21:36
3

does Docker actually clone the image

Typically no, it uses a layered filesystem, by default that's overlay2 on my systems. A decent example of this comes from the arch wiki:

  • The lower directory can be read-only or could be an overlay itself.
  • The upper directory is normally writable.
  • The workdir is used to prepare files as they are switched between the layers.

The lower directory can actually be a list of directories separated by :, all changes in the merged directory are still reflected in upper.

Example:

# mount -t overlay overlay -o lowerdir=/lower1:/lower2:/lower3,upperdir=/upper,workdir=/work /merged

how can I see the actual disk space used by a container?

Docker will show you the disk used by all containers in a docker system df.

$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          183       4         37.59GB   37.34GB (99%)
Containers      7         3         2.23kB    1.114kB (49%)
Local Volumes   10        1         4.816GB   305.8MB (6%)
Build Cache     511       0         20.49GB   20.49GB

For a container, this number is not static (unlike images that are read only), so I don't think this shows in any of the inspect commands. But you can see the underlying filesystems used:

$ docker container inspect 056 --format '{{json .GraphDriver}}' | jq .
{
  "Data": {
    "LowerDir": "/home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6-init/diff:/home/docker/overlay2/22281f31287edf3342709add6123436540bd04dea60e474c961421e47b2dd58f/diff:/home/docker/overlay2/6a7a1eee38c2496928dff4741c2f9a1365f177a3e620ef7cf8adb816bba69b55/diff:/home/docker/overlay2/fcf371f07f06a42d328027281afb52c8044000cb51c4bb01a1f0dca2701062ec/diff:/home/docker/overlay2/89f8b12195e051bc439ac66d2bb299975884cdb229146dd570b1cac4011a08e6/diff:/home/docker/overlay2/d5a7a5c1c11746080d802b4dd076fd4d775099cb16b73d82c06db71e93b4e0c5/diff",
    "MergedDir": "/home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6/merged",
    "UpperDir": "/home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6/diff",
    "WorkDir": "/home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6/work"
  },
  "Name": "overlay2"
}

In this case, I can look at the disk usage of UpperDir to see how much space is used by that container:

$ sudo du -sh /home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6/diff
80K     /home/docker/overlay2/ba813e6876186f8792d263ced7dc912921870393a085644188a8adadcf73d3e6/diff

The actual disk space used by a container includes the filesystem changes made by the container, since overlay is a copy-on-write filesystem. Each file changed is first copied to the container specific filesystem, even for a timestamp, permission, or owner change to the file metadata. This allows multiple containers to use the same immutable image layers without seeing changes made by the other containers.

Docker also keeps container logs, stdout and stderr, for each container. These logs are by default unlimited.

What you won't see is a full copy of the image filesystem, unless the overlay and similar graph drivers are unavailable to the docker engine. The fallback on an unsupported host filesystem, or kernel missing the needed features, is to use the vfs graph driver in docker, which I believe is the same as the native snapshotter in containerd. I see this happen occasionally with a docker-in-docker build environment where you cannot run an overlay filesystem on top of the overlay container filesystem (the fix there is typically to mount a volume that is on a supported filesystem outside of the container's overlay filesystem).

BMitch
  • 3,290
  • 9
  • 18
0

Docker containers are processes, does a process use disk space ? nope (at least not in itself).

The space used is the space when you put the program on disk first (the container image here).

Starting a container multiple times behave as starting bash/zsh/ multiple times when you login/ssh on different terminals/sessions.

One particularity of containers, more precisely of overlayfs, is the layers, if you pull two images for services based on the same base image, the initial layer won't be downloaded twice.

A rought illustration:

- Ubuntu 20.04
|- redis (FROM ubuntu 20.04)
|- apache2 (FROM ubuntu 20.04)

You can get image for apache2 and redis and get only 3 layers on disk, the base ubuntu 20.04 will be reused.

Refer to BMitch's answer for details

Tensibai
  • 11,366
  • 2
  • 35
  • 62
  • But when I delete a container and create a new one from the same image, the changes that I made in the first container are not persisted, i.e. the filesystem was reset; so the container does have a storage of its own somehow? Sorry I'm completely new to Docker. – BenMorel Dec 10 '20 at 22:58
  • Each container start from the image and get its own place, like booting from an iso image or creating multiple vms from the same template – Tensibai Dec 11 '20 at 12:15
  • This "own place" is the whole point of my question, I still find it hard to understand where/how this is actually stored. – BenMorel Dec 11 '20 at 13:02
  • It is stored somewhere in /var/lib/docker usually, the "layer" dedicated to the container only exists with the container, when you remove the container it is deleted. – Tensibai Dec 14 '20 at 08:08