Containers
banshee/containers-collection/containers/docker/ssh/
disk
The space the images, containers, volumes and build cache of a Docker host take, by SSH, through a restricted sudo or the docker group.
by banshee1 installation2 versions
v2Latest
Published on October 28, 2026. One naming convention across collections; documentation completed.
// The space Docker takes on the disk of a host, by SSH: for its images, its containers, its local volumes
// and its build cache, the space used, the space that could be freed, and how many there are and how many
// are in use. One command, docker system df, which only reads: through sudo -n in the one form the sudoers
// line of the documentation allows, or straight when the account is in the docker group.
// The free space of the disk itself is the filesystem collector's: this one says what Docker holds on it.
need('protocol:ssh');
$sudo = variable('docker:sudo', 'boolean', array(
'label' => 'Through sudo',
'help' => 'Runs docker through sudo, with the sudoers line of the documentation. Off when the account is in the docker group instead.',
'default' => true,
));
per('type', 'Types');
output('size', 'number', array('label' => 'Space used', 'unit' => 'GiB', 'per' => 'type'));
output('reclaimable', 'number', array('label' => 'Space that could be freed', 'unit' => 'GiB', 'per' => 'type'));
output('count', 'number', array('label' => 'Count', 'per' => 'type'));
output('active', 'number', array('label' => 'In use', 'per' => 'type'));
watch.above('size', 'Docker space used', 'size', array(
'help' => 'The threshold depends on the disk: in GiB.',
'enabled' => false,
));
watch.above('reclaimable', 'Space to free', 'reclaimable', array(
'help' => 'Images, containers, volumes or build cache that nothing uses any more, and that docker system prune would free: in GiB.',
'enabled' => false,
));
// Runs a docker command, through sudo -n when asked, and returns what it wrote. A daemon that does not
// answer is a host whose containers are all down: critical. Anything else that keeps docker from answering
// (sudo refusing, docker missing, the account outside the docker group) is a setting to fix.
function docker_run($sudo, $arguments) {
$command = '/usr/bin/docker ' . $arguments;
if ($sudo) {
$command = 'sudo -n ' . $command;
}
$read = ssh.run($command);
if ($read['exit'] != 0) {
if (text.contains($read['errors'], 'Cannot connect to the Docker daemon')) {
fail('critical', 'The Docker daemon is not running', $read['errors']);
}
if (text.contains($read['errors'], 'sudo')) {
fail('misconfigured', 'sudo refused to run docker: see the sudoers line of the documentation', $read['errors']);
}
fail('misconfigured', 'docker did not answer', $read['errors']);
}
return $read['output'];
}
// A size as Docker writes it, in decimal units, four significant figures: "16.43MB", "212B", "1.2GB (45%)";
// a space before the unit, as the documentation's example writes it, is read too. Returned in GiB, to the
// hundredth (about 10 MiB), the unit of space of every collector. '' when it is not one.
function gib_of($size) {
$units = array('B' => 1, 'kB' => 1000, 'MB' => 1000000, 'GB' => 1000000000, 'TB' => 1000000000000,
'PB' => 1000000000000000);
$m = text.match($size, '^([0-9.]+) ?(B|kB|MB|GB|TB|PB)');
if (list.count($m) == 0) {
return '';
}
return number.round($m[1] * $units[$m[2]] / 1073741824, 2);
}
// One JSON object per line, one line per type: {"Type": "Images", "TotalCount": "5", "Active": "2", "Size":
// "16.43MB", "Reclaimable": "11.63MB (70%)"}. The types are Images, Containers, Local Volumes and Build
// Cache; each is named in lower case, words joined by "-": local-volumes.
$output = docker_run($sudo, "system df --format '{{json .}}'");
$types = 0;
foreach (text.lines($output) as $line) {
$row = json.read($line);
$name = text.lower(text.join(text.words($row['Type']), '-'));
$types = $types + 1;
$size = gib_of($row['Size']);
if ($size != '') {
value('size', $size, $name);
}
$reclaimable = gib_of($row['Reclaimable']);
if ($reclaimable != '') {
value('reclaimable', $reclaimable, $name);
}
if (text.is_number($row['TotalCount'])) {
value('count', $row['TotalCount'] + 0, $name);
}
if (text.is_number($row['Active'])) {
value('active', $row['Active'] + 0, $name);
}
}
if ($types == 0) {
fail('misconfigured', 'docker system df returned nothing', $output);
}