Home >Backend Development >Golang >`docker system df` and `/system/df` (docker api endpoint)
php editor Yuzai is here to introduce to you two commands in docker: `docker system df` and `/system/df` (docker api endpoint). Both commands are used to view the docker system resource usage, but their usage and result display methods are slightly different. `docker system df` is a docker command that can be run directly in the terminal. It will display the usage of various resources in the docker system (including images, containers, data volumes, etc.), as well as the overall resource usage. And `/system/df` is a docker API endpoint, and you need to obtain relevant information by calling the API. Its return result is similar to `docker system df`, but it is more suitable for programmatically obtaining docker system resource usage.
I am writing a program in Go to get the total disk usage in GB from my docker host. For this I use func DiskUsage()
from go lib:
View the code, the function is calling the docker api endpoint /system/df
:
However, when I use this library with the calculation of GB using the command docker system df
, I notice a strange behavior:
docker system df
Output:
$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 223 4 21.02GB 20.7GB (98%) Containers 6 0 0B 0B Local Volumes 13 1 536.4MB 340.4MB (63%) Build Cache 954 0 13.51GB 13.51GB
$ go run ./cmd/main.go Images: TOTAL (223), 17GB Build Cache: TOTAL (954), 29GB
As you can see, there is a difference between the two outputs. I need help understanding if there is something wrong with my calculations that get the data from the /system/df
endpoint. Thanks:)
Go Application:
package main import ( "context" "fmt" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) func main() { cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { panic(err) } diskUsg, err := cli.DiskUsage(context.Background(), types.DiskUsageOptions{}) if err != nil { panic(err) } b := float64(0) for _, ch := range diskUsg.BuildCache { b = b + float64(ch.Size) } b2 := float64(0) for _, ch := range diskUsg.Images { if ch.Size > ch.SharedSize { b2 = b2 + (float64(ch.Size) - float64(ch.SharedSize)) continue } b2 = b2 + (float64(ch.SharedSize) - float64(ch.Size)) } fmt.Printf("Images: TOTAL (%d), %2.fGB\n", len(diskUsg.Images), float64(b2)/(1<<30)) fmt.Printf("Build Cache: TOTAL (%d), %2.fGB\n", len(diskUsg.BuildCache), float64(b)/(1<<30)) }
Based on Docker source code:
system df
Command: https://github.com/docker/cli/blob/v24.0.5/cli/command/system/df.go
You should be able to reproduce exactly what docker system df
does using the following code:
go.mod
module 76982562-docker-system-df-vs-system-df-docker-api-endpoint go 1.21.0 require ( github.com/docker/cli v24.0.5+incompatible github.com/docker/docker v24.0.5+incompatible )
main.go
<code>package main import ( "context" "fmt" "os" "github.com/docker/cli/cli/command/formatter" "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/docker/go-units" ) func main() { cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { panic(err) } diskUsage, err := cli.DiskUsage(context.Background(), types.DiskUsageOptions{}) if err != nil { panic(err) } var bsz int64 for _, bc := range diskUsage.BuildCache { if !bc.Shared { bsz += bc.Size } } fmt.Printf("Images: TOTAL (%d), %s\n", len(diskUsage.Images), units.HumanSize(float64(diskUsage.LayersSize))) fmt.Printf("Build Cache: TOTAL (%d), %s\n", len(diskUsage.BuildCache), units.HumanSize(float64(bsz))) } </code>
docker
library directly provides diskUsage.LayersSize
to represent the total size, so you don’t have to calculate it yourselfif !bc.Shared
) To convert the size in the correct units, I strongly recommend using github.com/docker/go-units
(e.g. units.HumanSize(float64(diskUsage.LayersSize))
) . This will save you the unit conversion nightmare!
The above is the detailed content of `docker system df` and `/system/df` (docker api endpoint). For more information, please follow other related articles on the PHP Chinese website!