348

I can see that Docker takes 12GB of my filesystem:

2.7G    /var/lib/docker/vfs/dir
2.7G    /var/lib/docker/vfs
2.8G    /var/lib/docker/devicemapper/mnt
6.3G    /var/lib/docker/devicemapper/devicemapper
9.1G    /var/lib/docker/devicemapper
12G     /var/lib/docker

But, how do I know how this is distributed over the containers?

I tried to attach to the containers by running (the new v1.3 command)

docker exec -it <container_name> bash

and then running df -h to analyze the disk usage. It seems to be working, but not with containers that use 'volumes-from'.

For example, I use a data-only container for MongoDB, called 'mongo-data'.

When I run docker run -it --volumes-from mongo-data busybox, and then df -h inside the container, It says that the filesystem mounted on /data/db (my 'mongo-data' data-only container) uses 11.3G, but when I do du -h /data/db, it says that it uses only 2.1G.

So, how do I analyze a container/volume disk usage? Or, in my case, how do I find out the 'mongo-data' container size?

James Skemp
  • 8,018
  • 9
  • 64
  • 107
AlonL
  • 6,100
  • 3
  • 33
  • 32
  • On Mac OS X there is a open issue "Docker doesn't release disk space...": https://github.com/docker/for-mac/issues/371 – asmaier Sep 06 '17 at 12:28
  • If you want to reduce the size of many-layered images, I can recommend Jason Wilder's ``docker-squash`` utility. Get it from GitHub here: https://github.com/jwilder/docker-squash – mhvelplund May 18 '16 at 11:16

11 Answers11

584

To see the file size of your containers, you can use the --size argument of docker ps:

docker ps --size
tshepang
  • 12,111
  • 21
  • 91
  • 136
Maxime
  • 9,638
  • 4
  • 17
  • 17
405

After 1.13.0, Docker includes a new command docker system df to show docker disk usage.

$ docker system df
TYPE            TOTAL        ACTIVE     SIZE        RECLAIMABLE
Images          5            1          2.777 GB    2.647 GB (95%)
Containers      1            1          0 B         0B
Local Volumes   4            1          3.207 GB    2.261 (70%)

To show more detailed information on space usage:

$ docker system df --verbose
tshepang
  • 12,111
  • 21
  • 91
  • 136
Hemerson Varela
  • 24,034
  • 16
  • 68
  • 69
31

Posting this as an answer because my comments above got hidden:

List the size of a container:

du -d 2 -h /var/lib/docker/devicemapper | grep `docker inspect -f "{{.Id}}" <container_name>`

List the sizes of a container's volumes:

docker inspect -f "{{.Volumes}}" <container_name> | sed 's/map\[//' | sed 's/]//' | tr ' ' '\n' | sed 's/.*://' | xargs sudo du -d 1 -h

Edit: List all running containers' sizes and volumes:

for d in `docker ps -q`; do
    d_name=`docker inspect -f {{.Name}} $d`
    echo "========================================================="
    echo "$d_name ($d) container size:"
    sudo du -d 2 -h /var/lib/docker/devicemapper | grep `docker inspect -f "{{.Id}}" $d`
    echo "$d_name ($d) volumes:"
    docker inspect -f "{{.Volumes}}" $d | sed 's/map\[//' | sed 's/]//' | tr ' ' '\n' | sed 's/.*://' | xargs sudo du -d 1 -h
done

NOTE: Change 'devicemapper' according to your Docker filesystem (e.g 'aufs')

AlonL
  • 6,100
  • 3
  • 33
  • 32
  • 8
    "du -d 2" does not work on my Centos system, I had to use "du --max-depth 2" instead. – dr-jan Apr 02 '15 at 13:53
  • 3
    On Mac it shows `/var/lib/docker/devicemapper: No such file or directory`. Any idea where the devicemapper is stored on mac? – Markus Apr 17 '15 at 13:03
  • 1
    Markus: if you are using boot2docker, you have to run the `du` command inside your boot2docker host VM. The command can also fail if you are using `aufs` instead of device mapper. – James May 19 '15 at 01:22
  • how about 'docker ps -q' to list the hashes of the containers instead of the awk/tail? – Andrew Wolfe Dec 18 '15 at 14:53
  • Container size is always blank on my Ubuntu 14.04/Docker 1.10.2 installation. – mhvelplund May 18 '16 at 11:19
21

The volume part did not work anymore so if anyone is insterested I just change the above script a little bit:

for d in `docker ps | awk '{print $1}' | tail -n +2`; do
    d_name=`docker inspect -f {{.Name}} $d`
    echo "========================================================="
    echo "$d_name ($d) container size:"
    sudo du -d 2 -h /var/lib/docker/aufs | grep `docker inspect -f "{{.Id}}" $d`
    echo "$d_name ($d) volumes:"
    for mount in `docker inspect -f "{{range .Mounts}} {{.Source}}:{{.Destination}}                                                                                                                                                      
    {{end}}" $d`; do
        size=`echo $mount | cut -d':' -f1 | sudo xargs du -d 0 -h`
        mnt=`echo $mount | cut -d':' -f2`
        echo "$size mounted on $mnt"
    done
done
Gilsha
  • 14,431
  • 3
  • 32
  • 47
Juanito
  • 211
  • 2
  • 2
  • Mount Points != Volumes – derFunk Jun 23 '16 at 19:52
  • 1
    Mac Docker 1.12.1 puts image files in ~/Library/Containers/com.docker.docker/ not /var/lib/docker/aufs. The filenames for which do not contain the .Id or the .Name :-( – paul_h Oct 08 '16 at 14:26
18

Improving Maxime's anwser:

docker ps --size

You'll see something like this:

+---------------+---------------+--------------------+
| CONTAINER ID  | IMAGE         | SIZE               |
+===============+===============+====================+
| 6ca0cef8db8d  | nginx         | 2B (virtual 183MB) |
| 3ab1a4d8dc5a  | nginx         | 5B (virtual 183MB) |
+---------------+---------------+--------------------+

When starting a container, the image that the container is started from is mounted read-only (virtual).
On top of that, a writable layer is mounted, in which any changes made to the container are written.

So the Virtual size (183MB in the example) is used only once, regardless of how many containers are started from the same image - I can start 1 container or a thousand; no extra disk space is used.
The "Size" (2B in the example) is unique per container though, so the total space used on disk is:

183MB + 5B + 2B

Be aware that the size shown does not include all disk space used for a container.
Things that are not included currently are;
- volumes
- swapping
- checkpoints
- disk space used for log-files generated by container

https://github.com/docker/docker.github.io/issues/1520#issuecomment-305179362

Channing Walton
  • 3,977
  • 1
  • 30
  • 59
danilo
  • 7,680
  • 7
  • 43
  • 46
17

I use docker stats $(docker ps --format={{.Names}}) --no-stream to get :

  1. CPU usage,
  2. Mem usage/Total mem allocated to container (can be allocate with docker run command)
  3. Mem %
  4. Block I/O
  5. Net I/O
Opal
  • 81,889
  • 28
  • 189
  • 210
Abhishek Jain
  • 3,815
  • 2
  • 26
  • 26
11

(this answer is not useful, but leaving it here since some of the comments may be)

docker images will show the 'virtual size', i.e. how much in total including all the lower layers. So some double-counting if you have containers that share the same base image.

documentation

Bryan
  • 11,398
  • 3
  • 53
  • 78
  • 3
    I'm not talking about the images, but about the containers (The list shown by running 'docker ps'). – AlonL Nov 05 '14 at 13:42
  • 1
    Containers are like processes; they don't have disk space. – Bryan Nov 05 '14 at 13:45
  • 2
    "The docker run command first creates a writeable container layer over the specified image..." (https://docs.docker.com/v1.1/reference/commandline/cli/) That layer is what I mean, or any other volumes that are mounted to the container via 'volumes-from', etc. – AlonL Nov 05 '14 at 14:29
  • 1
    Maybe this tool will help? https://github.com/cpuguy83/docker-volumes Referenced from http://container42.com/2014/11/03/docker-indepth-volumes/ – Bryan Nov 05 '14 at 16:31
  • 1
    Thanks, it doesn't satisfy my needs but it's a nice tool. – AlonL Nov 20 '14 at 10:27
  • OK, now I think I understand the question a bit better. My system uses aufs rather than devicemapper so I cannot be specific, but there are probably several directories under /var/lib/docker/devicemapper named with the ID of your container (the long hex number you can see in `docker ps --no-trunc`) - doing `du` on those should give sizes. – Bryan Nov 20 '14 at 11:17
  • Thanks, yeah, that's the best way I could find until now: `du -d 2 -h /var/lib/docker/devicemapper |grep 'docker inspect -f "{{.Id}}" '` (change ' to `) – AlonL Nov 20 '14 at 12:34
  • And, to list the sizes of a container's volumes I used: `docker inspect -f "{{.Volumes}}" | sed 's/map\[//' | sed 's/]//' | tr ' ' '\n' | sed 's/.*://' | xargs sudo du -d 1 -h` – AlonL Nov 20 '14 at 12:58
10

You can use

docker history IMAGE_ID

to see how the image size is ditributed between its various sub-components.

eiTan LaVi
  • 2,901
  • 24
  • 15
6

Keep in mind that docker ps --size may be an expensive command, taking more than a few minutes to complete. The same applies to container list API requests with size=1. It's better not to run it too often.

Take a look at alternatives we compiled, including the du -hs option for the docker persistent volume directory.

Nathan
  • 8,093
  • 8
  • 50
  • 76
Sergei Rodionov
  • 4,079
  • 6
  • 27
  • 44
4

The docker system df command displays information regarding the amount of disk space used by the docker daemon.

docker system df -v
logbasex
  • 1,688
  • 1
  • 16
  • 22
2

Alternative to docker ps --size

As "docker ps --size" produces heavy IO load on host, it is not feasable running such command every minute in a production environment. Therefore we have to do a workaround in order to get desired container size or to be more precise, the size of the RW-Layer with a low impact to systems perfomance.

This approach gathers the "device name" of every container and then checks size of it using "df" command. Those "device names" are thin provisioned volumes that a mounted to / on each container. One problem still persists as this observed size also implies all the readonly-layers of underlying image. In order to address this we can simple check size of used container image and substract it from size of a device/thin_volume.

One should note that every image layer is realized as a kind of a lvm snapshot when using device mapper. Unfortunately I wasn't able to get my rhel system to print out those snapshots/layers. Otherwise we could simply collect sizes of "latest" snapshots. Would be great if someone could make things clear. However...

After some tests, it seems that creation of a container always adds an overhead of approx. 40MiB (tested with containers based on Image "httpd:2.4.46-alpine"):

  1. docker run -d --name apache httpd:2.4.46-alpine // now get device name from docker inspect and look it up using df
  2. df -T -> 90MB whereas "Virtual Size" from "docker ps --size" states 50MB and a very small payload of 2Bytes -> mysterious overhead 40MB
  3. curl/download of a 100MB file within container
  4. df -T -> 190MB whereas "Virtual Size" from "docker ps --size" states 150MB and payload of 100MB -> overhead 40MB

Following shell prints results (in bytes) that match results from "docker ps --size" (but keep in mind mentioned overhead of 40MB)

for c in  $(docker ps -q); do \
container_name=$(docker inspect -f "{{.Name}}" ${c} | sed 's/^\///g' ); \
device_n=$(docker inspect -f "{{.GraphDriver.Data.DeviceName}}" ${c} | sed 's/.*-//g'); \
device_size_kib=$(df -T | grep ${device_n} | awk '{print $4}'); \
device_size_byte=$((1024 * ${device_size_kib})); \
image_sha=$(docker inspect -f "{{.Image}}" ${c} | sed 's/.*://g' ); \
image_size_byte=$(docker image inspect -f "{{.Size}}" ${image_sha}); \
container_size_byte=$((${device_size_byte} - ${image_size_byte})); \
\
echo my_node_dm_device_size_bytes\{cname=\"${container_name}\"\} ${device_size_byte}; \
echo my_node_dm_container_size_bytes\{cname=\"${container_name}\"\} ${container_size_byte}; \
echo my_node_dm_image_size_bytes\{cname=\"${container_name}\"\} ${image_size_byte}; \
done

Further reading about device mapper: https://test-dockerrr.readthedocs.io/en/latest/userguide/storagedriver/device-mapper-driver/