Andrew
Andrew

Reputation: 1

Get Docker Container Disk Usage as Percentage

Docker system df displays information on the amount of disk space used by the docker daemon.

TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              5                   2                   16.43 MB            11.63 MB (70%)
Containers          2                   0                   212 B               212 B (100%)
Local Volumes       2                   1                   36 B                0 B (0%)

I want to get the total disk usage as a percentage using the Go Docker client https://pkg.go.dev/github.com/docker/docker/client

{
  "LayersSize": 1092588,
  "Images": [
    {
      "Id": "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749",
      "ParentId": "",
      "RepoTags": [
        "busybox:latest"
      ],
      "RepoDigests": [
        "busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6"
      ],
      "Created": 1466724217,
      "Size": 1092588,
      "SharedSize": 0,
      "VirtualSize": 1092588,
      "Labels": {},
      "Containers": 1
    }
  ],
  "Containers": [
    {
      "Id": "e575172ed11dc01bfce087fb27bee502db149e1a0fad7c296ad300bbff178148",
      "Names": [
        "/top"
      ],
      "Image": "busybox",
      "ImageID": "sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749",
      "Command": "top",
      "Created": 1472592424,
      "Ports": [],
      "SizeRootFs": 1092588,
      "Labels": {},
      "State": "exited",
      "Status": "Exited (0) 56 minutes ago",
      "HostConfig": {
        "NetworkMode": "default"
      },
      "NetworkSettings": {
        "Networks": {
          "bridge": {
            "IPAMConfig": null,
            "Links": null,
            "Aliases": null,
            "NetworkID": "d687bc59335f0e5c9ee8193e5612e8aee000c8c62ea170cfb99c098f95899d92",
            "EndpointID": "8ed5115aeaad9abb174f68dcf135b49f11daf597678315231a32ca28441dec6a",
            "Gateway": "172.18.0.1",
            "IPAddress": "172.18.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "02:42:ac:12:00:02"
          }
        }
      },
      "Mounts": []
    }
  ],
  "Volumes": [
    {
      "Name": "my-volume",
      "Driver": "local",
      "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
      "Labels": null,
      "Scope": "local",
      "Options": null,
      "UsageData": {
        "Size": 10920104,
        "RefCount": 2
      }
    }
  ]
}

The remote api gives the json data. But I am not sure how to get exact disk usage from that.

Anyone had any luck doing this before?

Upvotes: 0

Views: 2069

Answers (1)

jubnzv
jubnzv

Reputation: 1584

The docker system df command prints only the size of reclaimable space in percents. Reclaimable is the space consumed by unused images, this is the total size of images you can remove without breaking anything.

Let's take a look at the source code of the docker CLI utility to better understand what docker system df does. There are two context of df usage: for docker images and for docker containers. The source code is pretty self-explanatory. For the containers we work with SizeRw (the size of the files which have been created or changed, if you compare the container to its base image) values to detect the percentage difference between the total size of containers and inactive containers. For docker images, we manipulate with the virtual and shared sizes of images for these purposes.

So based on your question, I assume that the data in percentages given by the docker system df is not what you really need. As I understand, you would like to get a percentage of the total disk space used by all containers or images.

This is not difficult to do. Let's get the total disk size, get the DiskUsage struct from the docker client and evaluate the required percentage:

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/docker/docker/client"
    "golang.org/x/sys/unix"
)

func main() {
    wd, err := os.Getwd()
    if err != nil {
        panic(err)
    }

    // Get amount of free disk space
    var stat unix.Statfs_t
    unix.Statfs(wd, &stat)

    // Available blocks * size per block = available space in bytes
    avail := stat.Bavail * uint64(stat.Bsize)

    // Create a docker client and request DiskUsage.
    // Replace this code with your own.
    cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
    if err != nil {
        panic(err)
    }
    du, err := cli.DiskUsage(context.Background())
    if err != nil {
        panic(err)
    }

    fmt.Printf("Available: %d bytes\n", avail)
    fmt.Printf("Space used: %f%%\n", 100-((float64)((int64)(avail)-du.LayersSize)/(float64)(avail))*100)
}

I assume that you are using *nix system. For Windows you can get the total amount of disk space using x/sys/windows package. See this answer for more information.

The above code prints the percentage of total disk space used by all layers. If you need the information for a specific container or image, you can use the fields of DiskUsage struct du that are described in the API reference.

I hope that you can easily rework this minimal example to fit your task.

Upvotes: 1

Related Questions