Skip to content

Commit e305b4e

Browse files
committed
Add .IPAddresses as formatting option on docker ps
This allows showing the IP address for each network that the container is attached to, for example: docker network create foo docker run -d --name foo nginx:alpine docker network connect foo foo container container ls --format 'table {{.ID}}\\t{{join .IPAddresses ", "}}' CONTAINER ID IP ADDRESSES 17e7d1910fc0 bridge:172.17.0.2, foo:172.19.0.2 container container ls --format='{{json .IPAddresses}}' | jq . [ "bridge:172.17.0.2", "foo:172.19.0.2" ] Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent abe4aa7 commit e305b4e

File tree

3 files changed

+88
-24
lines changed

3 files changed

+88
-24
lines changed

cli/command/formatter/container.go

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ import (
2121
const (
2222
defaultContainerTableFormat = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}"
2323

24-
namesHeader = "NAMES"
25-
commandHeader = "COMMAND"
26-
runningForHeader = "CREATED"
27-
mountsHeader = "MOUNTS"
28-
localVolumes = "LOCAL VOLUMES"
29-
networksHeader = "NETWORKS"
30-
platformHeader = "PLATFORM"
24+
namesHeader = "NAMES"
25+
commandHeader = "COMMAND"
26+
runningForHeader = "CREATED"
27+
mountsHeader = "MOUNTS"
28+
localVolumes = "LOCAL VOLUMES"
29+
networksHeader = "NETWORKS"
30+
platformHeader = "PLATFORM"
31+
ipAddressesHeader = "IP ADDRESSES"
3132
)
3233

3334
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
@@ -121,6 +122,7 @@ func NewContainerContext() *ContainerContext {
121122
"LocalVolumes": localVolumes,
122123
"Networks": networksHeader,
123124
"Platform": platformHeader,
125+
"IPAddresses": ipAddressesHeader,
124126
}
125127
return &containerCtx
126128
}
@@ -335,6 +337,25 @@ func (c *ContainerContext) Networks() string {
335337
return strings.Join(networks, ",")
336338
}
337339

340+
// IPAddresses returns the list of IP-addresses assigned to the container
341+
// IP-addresses are prefixed with the name of the network, separated with a colon.
342+
// For example: "bridge:192.168.1.10"
343+
func (c *ContainerContext) IPAddresses() []string {
344+
ipAddresses := []string{}
345+
if c.c.NetworkSettings == nil {
346+
return ipAddresses
347+
}
348+
for name, nw := range c.c.NetworkSettings.Networks {
349+
if nw.IPAddress != "" {
350+
ipAddresses = append(ipAddresses, name+":"+nw.IPAddress)
351+
}
352+
if nw.GlobalIPv6Address != "" {
353+
ipAddresses = append(ipAddresses, name+":"+nw.GlobalIPv6Address)
354+
}
355+
}
356+
return ipAddresses
357+
}
358+
338359
// DisplayablePorts returns formatted string representing open ports of container
339360
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
340361
// it's used by command 'docker ps'

cli/command/formatter/container_test.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/docker/cli/internal/test"
1515
"github.com/moby/moby/api/types/container"
16+
"github.com/moby/moby/api/types/network"
1617
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1718
"gotest.tools/v3/assert"
1819
is "gotest.tools/v3/assert/cmp"
@@ -352,7 +353,7 @@ size: 0B
352353
}
353354

354355
containers := []container.Summary{
355-
{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unixTime, State: container.StateRunning},
356+
{ID: "containerID1", Names: []string{"/foobar_baz"}, Image: "ubuntu", Created: unixTime, State: container.StateRunning, NetworkSettings: &container.NetworkSettingsSummary{}},
356357
{ID: "containerID2", Names: []string{"/foobar_bar"}, Image: "ubuntu", Created: unixTime, State: container.StateRunning},
357358
}
358359

@@ -538,6 +539,36 @@ func TestContainerContextWriteJSONField(t *testing.T) {
538539
}
539540
}
540541

542+
func TestContainerContextIPAddresses(t *testing.T) {
543+
containers := []container.Summary{
544+
{
545+
ID: "containerID1",
546+
NetworkSettings: &container.NetworkSettingsSummary{
547+
Networks: map[string]*network.EndpointSettings{
548+
"one": {IPAddress: "192.168.1.2"},
549+
"two": {IPAddress: "192.168.178.2"},
550+
},
551+
},
552+
},
553+
{
554+
ID: "containerID2",
555+
NetworkSettings: &container.NetworkSettingsSummary{
556+
Networks: map[string]*network.EndpointSettings{
557+
"one": {IPAddress: "192.168.1.3"},
558+
"two": {IPAddress: "192.168.178.3"},
559+
},
560+
},
561+
},
562+
}
563+
564+
out := bytes.NewBufferString("")
565+
err := ContainerWrite(Context{Format: "{{.IPAddresses}}", Output: out}, containers)
566+
assert.NilError(t, err)
567+
assert.Equal(t, out.String(), `[one:192.168.1.2 two:192.168.178.2]
568+
[one:192.168.1.3 two:192.168.178.3]
569+
`)
570+
}
571+
541572
func TestContainerBackCompat(t *testing.T) {
542573
createdAtTime := time.Now().AddDate(-1, 0, 0) // 1 year ago
543574

docs/reference/commandline/container_ls.md

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -395,22 +395,24 @@ template.
395395

396396
Valid placeholders for the Go template are listed below:
397397

398-
| Placeholder | Description |
399-
|:--------------|:------------------------------------------------------------------------------------------------|
400-
| `.ID` | Container ID |
401-
| `.Image` | Image ID |
402-
| `.Command` | Quoted command |
403-
| `.CreatedAt` | Time when the container was created. |
404-
| `.RunningFor` | Elapsed time since the container was started. |
405-
| `.Ports` | Exposed ports. |
406-
| `.State` | Container status (for example; "created", "running", "exited"). |
407-
| `.Status` | Container status with details about duration and health-status. |
408-
| `.Size` | Container disk size. |
409-
| `.Names` | Container names. |
410-
| `.Labels` | All labels assigned to the container. |
411-
| `.Label` | Value of a specific label for this container. For example `'{{.Label "com.docker.swarm.cpu"}}'` |
412-
| `.Mounts` | Names of the volumes mounted in this container. |
413-
| `.Networks` | Names of the networks attached to this container. |
398+
| Placeholder | Description |
399+
|:---------------|:------------------------------------------------------------------------------------------------|
400+
| `.ID` | Container ID |
401+
| `.Image` | Image ID |
402+
| `.Command` | Quoted command |
403+
| `.CreatedAt` | Time when the container was created. |
404+
| `.RunningFor` | Elapsed time since the container was started. |
405+
| `.Ports` | Exposed ports. |
406+
| `.State` | Container status (for example; "created", "running", "exited"). |
407+
| `.Status` | Container status with details about duration and health-status. |
408+
| `.Size` | Container disk size. |
409+
| `.Names` | Container names. |
410+
| `.Labels` | All labels assigned to the container. |
411+
| `.Label` | Value of a specific label for this container. For example `'{{.Label "com.docker.swarm.cpu"}}'` |
412+
| `.Mounts` | Names of the volumes mounted in this container. |
413+
| `.Networks` | Names of the networks attached to this container. |
414+
| `.IPAddresses` | List of IP-Addresses for each network that the container is attached to. |
415+
414416

415417
When using the `--format` option, the `ps` command will either output the data
416418
exactly as the template declares or, when using the `table` directive, includes
@@ -446,3 +448,13 @@ To list all running containers in JSON format, use the `json` directive:
446448
$ docker ps --format json
447449
{"Command":"\"/docker-entrypoint.…\"","CreatedAt":"2021-03-10 00:15:05 +0100 CET","ID":"a762a2b37a1d","Image":"nginx","Labels":"maintainer=NGINX Docker Maintainers \[email protected]\u003e","LocalVolumes":"0","Mounts":"","Names":"boring_keldysh","Networks":"bridge","Ports":"80/tcp","RunningFor":"4 seconds ago","Size":"0B","State":"running","Status":"Up 3 seconds"}
448450
```
451+
452+
Show the IP-addresses that containers have:
453+
454+
```console
455+
$ docker ps --format "table {{.ID}}\\t{{join .IPAddresses \", \"}}"
456+
457+
CONTAINER ID IP ADDRESSES
458+
c0cf2877da71 bridge:172.17.0.3
459+
17e7d1910fc0 bridge:172.17.0.2, mynetwork:172.19.0.2
460+
```

0 commit comments

Comments
 (0)