I don’t think EXPOSE really does much of practical interest. If you docker run -P then Docker will publish all exposed ports on to random host ports, but that’s of minimal usefulness; you’re better off explicitly docker run -p to explicitly publish individual ports, which don’t necessarily need to be “exposed”.
The only thing that really leaves is, like labels, information that can be found by docker inspect on an image. I don’t know if there are any tools that display than information. But I’d probably leave the EXPOSE line in my Dockerfile as a hint to the next person to maintain the system as to what I expect it to do.
The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. To actually publish the port when running the container, use the -p flag on docker run to publish and map one or more ports, or the -P flag to publish all exposed ports and map them to high-order ports.
Remember that -P uses an ephemeral high-ordered host port on the host, so the port will not be the same for TCP and UDP.
And from the CLI documentation (docker help run):
-P, --publish-all Publish all exposed ports to random ports