How do I use docker command's “--format” option?
I can't seem to find any good documentation on how to use the docker command's "--format" option in real life. I know how to use Go templates. But specific to docker, how do I know what placeholders are available to use?
I tried docker inspect
on a container and I see JSON output, but I can't use the names from that as Go template placeholders. I did find out that the placeholders are case-sensitive, which seems unfortunate. The default output isn't much help either, since (I assume) it isn't showing me everything I might use, the columns that are there are all uppercase, and they sometimes have spaces in them. docker container ls
, for example, has a column called "CONTAINER ID". No combination of underscores, quoting schemes, or so on will make that name work. I figured out that it's "{{.ID}}".
How am I supposed to be using "--format"? How do I discover placeholders for any given docker object?
docker go
add a comment |
I can't seem to find any good documentation on how to use the docker command's "--format" option in real life. I know how to use Go templates. But specific to docker, how do I know what placeholders are available to use?
I tried docker inspect
on a container and I see JSON output, but I can't use the names from that as Go template placeholders. I did find out that the placeholders are case-sensitive, which seems unfortunate. The default output isn't much help either, since (I assume) it isn't showing me everything I might use, the columns that are there are all uppercase, and they sometimes have spaces in them. docker container ls
, for example, has a column called "CONTAINER ID". No combination of underscores, quoting schemes, or so on will make that name work. I figured out that it's "{{.ID}}".
How am I supposed to be using "--format"? How do I discover placeholders for any given docker object?
docker go
add a comment |
I can't seem to find any good documentation on how to use the docker command's "--format" option in real life. I know how to use Go templates. But specific to docker, how do I know what placeholders are available to use?
I tried docker inspect
on a container and I see JSON output, but I can't use the names from that as Go template placeholders. I did find out that the placeholders are case-sensitive, which seems unfortunate. The default output isn't much help either, since (I assume) it isn't showing me everything I might use, the columns that are there are all uppercase, and they sometimes have spaces in them. docker container ls
, for example, has a column called "CONTAINER ID". No combination of underscores, quoting schemes, or so on will make that name work. I figured out that it's "{{.ID}}".
How am I supposed to be using "--format"? How do I discover placeholders for any given docker object?
docker go
I can't seem to find any good documentation on how to use the docker command's "--format" option in real life. I know how to use Go templates. But specific to docker, how do I know what placeholders are available to use?
I tried docker inspect
on a container and I see JSON output, but I can't use the names from that as Go template placeholders. I did find out that the placeholders are case-sensitive, which seems unfortunate. The default output isn't much help either, since (I assume) it isn't showing me everything I might use, the columns that are there are all uppercase, and they sometimes have spaces in them. docker container ls
, for example, has a column called "CONTAINER ID". No combination of underscores, quoting schemes, or so on will make that name work. I figured out that it's "{{.ID}}".
How am I supposed to be using "--format"? How do I discover placeholders for any given docker object?
docker go
docker go
asked 11 hours ago
Todd WaltonTodd Walton
1113
1113
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq
. Anyway:
Formatting expect
commands
sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
{
"Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
"Created": "2019-02-05T16:41:40.040349047Z",
"Path": "sleep",
"Args": [
"3000"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
"ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
"HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
"LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
"Name": "/vibrant_shaw",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": ,
"DnsOptions": ,
"DnsSearch": ,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": ,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": ,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": ,
"Config": {
"Hostname": "0470a3549d2f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"3000"
],
"Image": "busybox",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/654da638965d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
Returning scalar properties
You can query any scalar attribute by its name, prefixed by a dot:
sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs
# jq notation
sh$ sudo docker inspect $CID | jq '..Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"
sh$ sudo docker inspect $CID | jq '.|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"
You can also query nested fields:
sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true
# jq notation
sudo docker inspect $CID | jq '..State.Running'
true
Returning entire objects and arrays
But it does not work as expected for nested structures:
sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0 2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}
You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).
When accessing entire objects, there are chances you want an explicit formatter:
sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}
# jq notation
sh$ sudo docker inspect $CID | jq '..State'
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
Same thing for arrays:
sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger
# jq notation
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths'
[
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"
Arrays of objects
More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:
# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'
Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}
When I want to extract such nested value, I resort on an explicit range loop:
sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1
# jq notation
sh$ sudo docker network inspect bridge | jq '..IPAM.Config.Gateway'
"172.17.0.1"
sh$ sudo docker network inspect bridge | jq -r '..IPAM.Config.Gateway'
172.17.0.1
Formatting ls
commands
With the json
formatter, we can obtain (some? all?) the possible selectors you can later use with --format
:
sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}
Here, you can see docker network ls
exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:
sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)
The best of both worlds
The docker ... ls
commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q)
.
For example, docker image ls
does not export the image architecture. but you can obtain it with docker image inspect
. If you want that information, you could use something like that:
sh$ sudo docker image inspect
--format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})'
$(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)
1
It seems like your examples all depend on the command being "inspect". This works:docker inspect $CID --format '{{.Id}}'
. But this doesn't work:docker container ls --format '{{.Id}}'
.
– Todd Walton
7 hours ago
1
@ToddWalton You can always use--format '{{json .}}
to inspect the fields exported by anls
command. I've edited my answer to add a section at the end showing how to do that.
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of thedocker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines ofdocker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "674"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdevops.stackexchange.com%2fquestions%2f6241%2fhow-do-i-use-docker-commands-format-option%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq
. Anyway:
Formatting expect
commands
sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
{
"Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
"Created": "2019-02-05T16:41:40.040349047Z",
"Path": "sleep",
"Args": [
"3000"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
"ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
"HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
"LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
"Name": "/vibrant_shaw",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": ,
"DnsOptions": ,
"DnsSearch": ,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": ,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": ,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": ,
"Config": {
"Hostname": "0470a3549d2f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"3000"
],
"Image": "busybox",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/654da638965d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
Returning scalar properties
You can query any scalar attribute by its name, prefixed by a dot:
sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs
# jq notation
sh$ sudo docker inspect $CID | jq '..Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"
sh$ sudo docker inspect $CID | jq '.|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"
You can also query nested fields:
sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true
# jq notation
sudo docker inspect $CID | jq '..State.Running'
true
Returning entire objects and arrays
But it does not work as expected for nested structures:
sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0 2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}
You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).
When accessing entire objects, there are chances you want an explicit formatter:
sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}
# jq notation
sh$ sudo docker inspect $CID | jq '..State'
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
Same thing for arrays:
sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger
# jq notation
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths'
[
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"
Arrays of objects
More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:
# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'
Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}
When I want to extract such nested value, I resort on an explicit range loop:
sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1
# jq notation
sh$ sudo docker network inspect bridge | jq '..IPAM.Config.Gateway'
"172.17.0.1"
sh$ sudo docker network inspect bridge | jq -r '..IPAM.Config.Gateway'
172.17.0.1
Formatting ls
commands
With the json
formatter, we can obtain (some? all?) the possible selectors you can later use with --format
:
sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}
Here, you can see docker network ls
exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:
sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)
The best of both worlds
The docker ... ls
commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q)
.
For example, docker image ls
does not export the image architecture. but you can obtain it with docker image inspect
. If you want that information, you could use something like that:
sh$ sudo docker image inspect
--format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})'
$(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)
1
It seems like your examples all depend on the command being "inspect". This works:docker inspect $CID --format '{{.Id}}'
. But this doesn't work:docker container ls --format '{{.Id}}'
.
– Todd Walton
7 hours ago
1
@ToddWalton You can always use--format '{{json .}}
to inspect the fields exported by anls
command. I've edited my answer to add a section at the end showing how to do that.
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of thedocker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines ofdocker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
add a comment |
I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq
. Anyway:
Formatting expect
commands
sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
{
"Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
"Created": "2019-02-05T16:41:40.040349047Z",
"Path": "sleep",
"Args": [
"3000"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
"ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
"HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
"LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
"Name": "/vibrant_shaw",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": ,
"DnsOptions": ,
"DnsSearch": ,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": ,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": ,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": ,
"Config": {
"Hostname": "0470a3549d2f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"3000"
],
"Image": "busybox",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/654da638965d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
Returning scalar properties
You can query any scalar attribute by its name, prefixed by a dot:
sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs
# jq notation
sh$ sudo docker inspect $CID | jq '..Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"
sh$ sudo docker inspect $CID | jq '.|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"
You can also query nested fields:
sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true
# jq notation
sudo docker inspect $CID | jq '..State.Running'
true
Returning entire objects and arrays
But it does not work as expected for nested structures:
sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0 2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}
You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).
When accessing entire objects, there are chances you want an explicit formatter:
sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}
# jq notation
sh$ sudo docker inspect $CID | jq '..State'
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
Same thing for arrays:
sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger
# jq notation
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths'
[
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"
Arrays of objects
More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:
# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'
Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}
When I want to extract such nested value, I resort on an explicit range loop:
sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1
# jq notation
sh$ sudo docker network inspect bridge | jq '..IPAM.Config.Gateway'
"172.17.0.1"
sh$ sudo docker network inspect bridge | jq -r '..IPAM.Config.Gateway'
172.17.0.1
Formatting ls
commands
With the json
formatter, we can obtain (some? all?) the possible selectors you can later use with --format
:
sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}
Here, you can see docker network ls
exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:
sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)
The best of both worlds
The docker ... ls
commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q)
.
For example, docker image ls
does not export the image architecture. but you can obtain it with docker image inspect
. If you want that information, you could use something like that:
sh$ sudo docker image inspect
--format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})'
$(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)
1
It seems like your examples all depend on the command being "inspect". This works:docker inspect $CID --format '{{.Id}}'
. But this doesn't work:docker container ls --format '{{.Id}}'
.
– Todd Walton
7 hours ago
1
@ToddWalton You can always use--format '{{json .}}
to inspect the fields exported by anls
command. I've edited my answer to add a section at the end showing how to do that.
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of thedocker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines ofdocker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
add a comment |
I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq
. Anyway:
Formatting expect
commands
sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
{
"Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
"Created": "2019-02-05T16:41:40.040349047Z",
"Path": "sleep",
"Args": [
"3000"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
"ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
"HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
"LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
"Name": "/vibrant_shaw",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": ,
"DnsOptions": ,
"DnsSearch": ,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": ,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": ,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": ,
"Config": {
"Hostname": "0470a3549d2f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"3000"
],
"Image": "busybox",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/654da638965d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
Returning scalar properties
You can query any scalar attribute by its name, prefixed by a dot:
sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs
# jq notation
sh$ sudo docker inspect $CID | jq '..Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"
sh$ sudo docker inspect $CID | jq '.|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"
You can also query nested fields:
sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true
# jq notation
sudo docker inspect $CID | jq '..State.Running'
true
Returning entire objects and arrays
But it does not work as expected for nested structures:
sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0 2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}
You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).
When accessing entire objects, there are chances you want an explicit formatter:
sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}
# jq notation
sh$ sudo docker inspect $CID | jq '..State'
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
Same thing for arrays:
sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger
# jq notation
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths'
[
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"
Arrays of objects
More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:
# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'
Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}
When I want to extract such nested value, I resort on an explicit range loop:
sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1
# jq notation
sh$ sudo docker network inspect bridge | jq '..IPAM.Config.Gateway'
"172.17.0.1"
sh$ sudo docker network inspect bridge | jq -r '..IPAM.Config.Gateway'
172.17.0.1
Formatting ls
commands
With the json
formatter, we can obtain (some? all?) the possible selectors you can later use with --format
:
sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}
Here, you can see docker network ls
exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:
sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)
The best of both worlds
The docker ... ls
commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q)
.
For example, docker image ls
does not export the image architecture. but you can obtain it with docker image inspect
. If you want that information, you could use something like that:
sh$ sudo docker image inspect
--format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})'
$(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)
I take the risk of being downvoted here, but I find Go templates a nightmare to use beyond the most basic use cases. Don't take me wrong: they are extremely powerful as you can guess it by reading the docs, but I find the syntax unfriendly, and for the most complex cases, I prefer parsing the JSON output with jq
. Anyway:
Formatting expect
commands
sho$ CID=$(sudo docker run --rm -d busybox sleep 3000)
sh$ sudo docker inspect $CID
[
{
"Id": "0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967",
"Created": "2019-02-05T16:41:40.040349047Z",
"Path": "sleep",
"Args": [
"3000"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444",
"ResolvConfPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hostname",
"HostsPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/hosts",
"LogPath": "/var/lib/docker/containers/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967/0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967-json.log",
"Name": "/vibrant_shaw",
"RestartCount": 0,
"Driver": "aufs",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": true,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": ,
"DnsOptions": ,
"DnsSearch": ,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "shareable",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": ,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": ,
"DeviceCgroupRules": null,
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": null,
"Name": "aufs"
},
"Mounts": ,
"Config": {
"Hostname": "0470a3549d2f",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sleep",
"3000"
],
"Image": "busybox",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "654da638965d9bb26e394ba61036ea713bdccb6304eb09bee86f3c0611a26ca5",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/654da638965d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "5ec8728b05efd5ce6bfde5cbe6e42f247348345e0fdfb305fda76566327fc151",
"EndpointID": "c69ef9cb870a3c477105c7bc19e370683886e4e3c62fac8444d3e1e097551250",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
Returning scalar properties
You can query any scalar attribute by its name, prefixed by a dot:
sh$ sudo docker inspect $CID --format '{{.Id}}
0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967
sh$ sudo docker inspect $CID --format '{{.Name}} {{.Driver}}'
/vibrant_shaw aufs
# jq notation
sh$ sudo docker inspect $CID | jq '..Id'
"0470a3549d2f41efd0477cf8fc4eb3a27aca592f089c018ad24704031bbef967"
sh$ sudo docker inspect $CID | jq '.|(.Name,.Driver)'
"/vibrant_shaw"
"aufs"
You can also query nested fields:
sh$ sudo docker inspect $CID --format '{{.State.Running}}'
true
# jq notation
sudo docker inspect $CID | jq '..State.Running'
true
Returning entire objects and arrays
But it does not work as expected for nested structures:
sh$ sudo docker inspect $CID --format '{{.State}}'
{running true false false false false 26467 0 2019-02-05T16:41:40.659056612Z 0001-01-01T00:00:00Z <nil>}
You end up having the data, but without the field names, it is pretty useless--unless you are assuming some predefined field order (something that is probably not safe).
When accessing entire objects, there are chances you want an explicit formatter:
sh$ sudo docker inspect $CID --format '{{json .State}}'
{"Status":"running","Running":true,"Paused":false,"Restarting":false,"OOMKilled":false,"Dead":false,"Pid":26467,"ExitCode":0,"Error":"","StartedAt":"2019-02-05T16:41:40.659056612Z","FinishedAt":"0001-01-01T00:00:00Z"}
# jq notation
sh$ sudo docker inspect $CID | jq '..State'
{
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 26467,
"ExitCode": 0,
"Error": "",
"StartedAt": "2019-02-05T16:41:40.659056612Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
Same thing for arrays:
sh$ sudo docker inspect $CID --format '{{.HostConfig.ReadonlyPaths}}'
[/proc/asound /proc/bus /proc/fs /proc/irq /proc/sys /proc/sysrq-trigger]
sh$ sudo docker inspect $CID --format '{{json .HostConfig.ReadonlyPaths}}'
["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]
sh$ sudo docker inspect $CID --format '{{join .HostConfig.ReadonlyPaths ":"}}'
/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger
# jq notation
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths'
[
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
sh$ sudo docker inspect $CID | jq '..HostConfig.ReadonlyPaths | join(":")'
"/proc/asound:/proc/bus:/proc/fs:/proc/irq:/proc/sys:/proc/sysrq-trigger"
Arrays of objects
More complicated (according to my limited Go Template skills) is accessing fields nested in an array of objects:
# This works as expected
sh$ sudo docker network inspect bridge --format '{{json .IPAM.Config}}'
[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
# But not that
sudo docker network inspect bridge --format '{{.IPAM.Config.Gateway}}'
Template parsing error: template: :1:7: executing "" at <.IPAM.Config.Gateway>: can't evaluate field Gateway in type interface {}
When I want to extract such nested value, I resort on an explicit range loop:
sh$ sudo docker network inspect bridge --format '{{range .IPAM.Config}}{{.Gateway}}{{end}}'
172.17.0.1
# jq notation
sh$ sudo docker network inspect bridge | jq '..IPAM.Config.Gateway'
"172.17.0.1"
sh$ sudo docker network inspect bridge | jq -r '..IPAM.Config.Gateway'
172.17.0.1
Formatting ls
commands
With the json
formatter, we can obtain (some? all?) the possible selectors you can later use with --format
:
sh$ sudo docker network ls --format '{{json .}}'
{"CreatedAt":"2019-01-07 14:28:55.63238018 +0100 CET","Driver":"bridge","ID":"5ec8728b05ef","IPv6":"false","Internal":"false","Labels":"","Name":"bridge","Scope":"local"}
{"CreatedAt":"2019-02-05 15:36:57.701603791 +0100 CET","Driver":"bridge","ID":"45d6f09ca923","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=default,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_default","Scope":"local"}
{"CreatedAt":"2019-02-05 17:30:47.98883918 +0100 CET","Driver":"bridge","ID":"aaff418d1c56","IPv6":"false","Internal":"false","Labels":"com.docker.compose.network=net,com.docker.compose.project=compose-demo,com.docker.compose.version=1.23.2","Name":"compose-demo_net","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.149819089 +0200 CEST","Driver":"host","ID":"988954899b53","IPv6":"false","Internal":"false","Labels":"","Name":"host","Scope":"local"}
{"CreatedAt":"2018-05-26 10:31:48.118573602 +0200 CEST","Driver":"null","ID":"ce1680ed377f","IPv6":"false","Internal":"false","Labels":"","Name":"none","Scope":"local"}
{"CreatedAt":"2019-02-05 19:44:21.286955573 +0100 CET","Driver":"bridge","ID":"41c62c023d16","IPv6":"false","Internal":"false","Labels":"com.docker.compose.version=1.23.2,com.docker.compose.network=default,com.docker.compose.project=test","Name":"test_default","Scope":"local"}
Here, you can see docker network ls
exposes, among others, the "ID", "Driver" and "Scope" fields. You can use them in your format:
sh$ $ sudo docker network ls --format '{{.ID}}: {{.Driver}} ({{.Scope}})'
5ec8728b05ef: bridge (local)
45d6f09ca923: bridge (local)
aaff418d1c56: bridge (local)
988954899b53: host (local)
ce1680ed377f: null (local)
41c62c023d16: bridge (local)
The best of both worlds
The docker ... ls
commands only exports a small subset of the docker object's properties. Depending your needs, you may prefer something along the lines of docker ... inspect $(docker ... ls -q)
.
For example, docker image ls
does not export the image architecture. but you can obtain it with docker image inspect
. If you want that information, you could use something like that:
sh$ sudo docker image inspect
--format '{{.Id}}: {{.RepoTags}} ({{.Architecture}})'
$(sudo docker image ls -q)
sha256:fc37804350a8adea0b41dba0c413a6c967140ca2ed6dfeefdbe88d7868902406: [compose-demo_monitor:latest] (amd64)
sha256:a6f30c0890bca94e3cf5930ad5c3358b06cb38450e92d4ddabeb208ee34383f8: [compose-demo_app:latest] (amd64)
sha256:a79892b33e0bb51598e9311cc1d23ca8d0e3013a5a15fd67d202d22ffd08a6af: (amd64)
sha256:394c82635f220db389b8532e316001674965b51679dbc8dff747d5f224e6d568: (amd64)
sha256:95f0c755feb65af441c0cb8727bb13b35517977a3bed06e4a3456c95d6a69dd4: [redis:5.0-alpine] (amd64)
sha256:1f6c34f7921c7b50ef4452737399b5cff0eb834fc183d188d82886fd23b7fc34: [node:8] (amd64)
sha256:3a093384ac306cbac30b67f1585e12b30ab1a899374dabc3170b9bca246f1444: [busybox:latest] (amd64)
edited 6 hours ago
answered 9 hours ago
Sylvain LerouxSylvain Leroux
46711
46711
1
It seems like your examples all depend on the command being "inspect". This works:docker inspect $CID --format '{{.Id}}'
. But this doesn't work:docker container ls --format '{{.Id}}'
.
– Todd Walton
7 hours ago
1
@ToddWalton You can always use--format '{{json .}}
to inspect the fields exported by anls
command. I've edited my answer to add a section at the end showing how to do that.
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of thedocker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines ofdocker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
add a comment |
1
It seems like your examples all depend on the command being "inspect". This works:docker inspect $CID --format '{{.Id}}'
. But this doesn't work:docker container ls --format '{{.Id}}'
.
– Todd Walton
7 hours ago
1
@ToddWalton You can always use--format '{{json .}}
to inspect the fields exported by anls
command. I've edited my answer to add a section at the end showing how to do that.
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of thedocker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines ofdocker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
1
1
It seems like your examples all depend on the command being "inspect". This works:
docker inspect $CID --format '{{.Id}}'
. But this doesn't work: docker container ls --format '{{.Id}}'
.– Todd Walton
7 hours ago
It seems like your examples all depend on the command being "inspect". This works:
docker inspect $CID --format '{{.Id}}'
. But this doesn't work: docker container ls --format '{{.Id}}'
.– Todd Walton
7 hours ago
1
1
@ToddWalton You can always use
--format '{{json .}}
to inspect the fields exported by an ls
command. I've edited my answer to add a section at the end showing how to do that.– Sylvain Leroux
7 hours ago
@ToddWalton You can always use
--format '{{json .}}
to inspect the fields exported by an ls
command. I've edited my answer to add a section at the end showing how to do that.– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of the
docker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines of docker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
@ToddWalton BTW, I suspect, like their shell counterpart, the output of the
docker ... ls
commands are for "human consumption". Depending on your use case, you might consider something along the lines of docker image inspect --format ... $(docker image ls -q)
– Sylvain Leroux
7 hours ago
add a comment |
Thanks for contributing an answer to DevOps Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdevops.stackexchange.com%2fquestions%2f6241%2fhow-do-i-use-docker-commands-format-option%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown