Open kindlychung opened 6 years ago
The UX is for getting the host port of a container where as the -p
syntax is for setting the host port of the container.
The format itself is also actually a list:
$ docker run -d --name test -p 80 -p 443 nginx
c85d2645be9dddab9af48858c3746328dd4673a321f20214ffd62e6552223783
~ $ docker port test
443/tcp -> 0.0.0.0:32769
80/tcp -> 0.0.0.0:32770
It also supports pulling the host port for a specific container port:
$ docker port test 80
0.0.0.0:32770
I don't think we can change the default output of docker ports
without breaking people.
FWIW, there was a PR at some point to add --format
to the docker port
command (PR here: https://github.com/moby/moby/pull/31859), but there was no consensus on adding more features to the command (docker port
is a bit of an odd-one out, as it overlaps in functionality with docker container inspect
/ docker inspect
, and there are no comparable commands for other properties of a container)
For now, you could use docker container inspect
to achieve this;
Start a container, that publishes some ports on ephemeral ("random") ports;
docker run -d -p 80 -p 443 -p 8080 --name test nginx:alpine
8f47e335b3e446972bcbd2abb6829b453adbc93cac743af7e5860d26b0a1f961
The docker port
command shows the standard format;
docker port test
443/tcp -> 0.0.0.0:32770
80/tcp -> 0.0.0.0:32771
8080/tcp -> 0.0.0.0:32769
But you can use custom formatting on docker container inspect
to use your own format;
docker container inspect --format '{{.NetworkSettings.Ports}}' test
map[80/tcp:[{0.0.0.0 32768}]]
docker container inspect --format '{{json .NetworkSettings.Ports}}' test
{"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"32768"}]}
For these arrays/lists, it's a bit complicated to write the template, but here's an example;
docker container inspect --format '{{ range $key, $value := .NetworkSettings.Ports }}{{ range . }}{{ .HostIp }}:{{ .HostPort}} -> {{ $key }}, {{end}}{{ end }}' test
0.0.0.0:32770->443/tcp, 0.0.0.0:32771->80/tcp, 0.0.0.0:32769->8080/tcp,
If you need a newline (I think) you have to add a literal newline in the template (don't think it expands \n
);
docker container inspect --format '{{ range $key, $value := .NetworkSettings.Ports }}{{ range . }}{{ .HostIp }}:{{ .HostPort}} -> {{ $key }}
{{end}}{{ end }}' test
Or have bash expand the newline;
docker container inspect --format '{{ range $key, $value := .NetworkSettings.Ports }}{{ range . }}{{ .HostIp }}:{{ .HostPort}} -> {{ $key }}'$'\n''{{end}}{{ end }}' test
You can set define this a function in your shell (or add to, e.g., your ~/.bashrc
)
docker_ports() {
docker container inspect --format '{{ range $key, $value := .NetworkSettings.Ports }}{{ range . }}{{ .HostIp }}:{{ .HostPort}} -> {{ $key }}'$'\n''{{end}}{{ end }}' "$@";
}
First, load the function
. ~/.bashrc
And you can now run docker_ports <container>
to use your custom output
docker_ports test
0.0.0.0:32770 -> 443/tcp
0.0.0.0:32771 -> 80/tcp
0.0.0.0:32769 -> 8080/tcp
Expected behavior
Order of ports should be consistent.
Actual behavior
docker run -p
has the format<external_ip>:<external_port>:<container_port>
, while the ports reported bydocker port
has the format<container_port>/protocal -> <external_ip>:<external_port>
.Output of
docker version
:Output of
docker info
: