Skip to content

Commit 397a379

Browse files
committed
formatter: suppress duplicate IPv6 wildcard port in docker ps output
When a port is bound on both 0.0.0.0 and ::, hide the IPv6 entry and show only the IPv4 entry to reduce noise in docker ps output. Before: 0.0.0.0:8080->80/tcp, :::8080->80/tcp After: 0.0.0.0:8080->80/tcp Fixes #6869
1 parent cbeeefe commit 397a379

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

cli/command/formatter/container.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,24 @@ func DisplayablePorts(ports []container.PortSummary) string {
364364
var result []string
365365
var hostMappings []string
366366
var groupMapKeys []string
367+
368+
// Pre-pass: record which (hostPort, privatePort, proto) tuples have an
369+
// IPv4 wildcard (0.0.0.0) binding. Used below to suppress the matching
370+
// IPv6 wildcard (::) entry, avoiding duplicate output such as:
371+
// 0.0.0.0:8080->80/tcp, :::8080->80/tcp
372+
// See: https://github.com/docker/cli/issues/6869
373+
type mappingKey struct {
374+
hostPort uint16
375+
privatePort uint16
376+
proto string
377+
}
378+
ipv4Bindings := make(map[mappingKey]bool)
379+
for _, port := range ports {
380+
if port.IP.String() == "0.0.0.0" && port.PublicPort != 0 {
381+
ipv4Bindings[mappingKey{port.PublicPort, port.PrivatePort, port.Type}] = true
382+
}
383+
}
384+
367385
sort.Slice(ports, func(i, j int) bool {
368386
return comparePorts(ports[i], ports[j])
369387
})
@@ -373,6 +391,18 @@ func DisplayablePorts(ports []container.PortSummary) string {
373391
portKey := port.Type
374392
if port.IP.IsValid() {
375393
if port.PublicPort != current {
394+
// Suppress the IPv6 wildcard entry when an IPv4 wildcard
395+
// entry already covers the same (hostPort, privatePort, proto)
396+
// tuple. This merges:
397+
// 0.0.0.0:8080->80/tcp, :::8080->80/tcp
398+
// into the cleaner:
399+
// 0.0.0.0:8080->80/tcp
400+
if port.IP.Is6() && !port.IP.Is4In6() && port.IP.IsUnspecified() {
401+
key := mappingKey{port.PublicPort, port.PrivatePort, port.Type}
402+
if ipv4Bindings[key] {
403+
continue
404+
}
405+
}
376406
hAddrPort := net.JoinHostPort(port.IP.String(), strconv.Itoa(int(port.PublicPort)))
377407
hostMappings = append(hostMappings, fmt.Sprintf("%s->%d/%s", hAddrPort, port.PrivatePort, port.Type))
378408
continue
@@ -435,4 +465,4 @@ func comparePorts(i, j container.PortSummary) bool {
435465
}
436466

437467
return i.Type < j.Type
438-
}
468+
}

0 commit comments

Comments
 (0)