Should containers in the default bridge network allow connections to host and other containers attached to this same network without EXPOSEing ports?
- Created a container with web service listening on port 8787.
- Failed to reveal any port through either Dockerfile EXPOSE command or
docker run --expose.
docker runcommand properly attached the Container to default bridge network.
docker psreported any exposed ports for the involved containers.
- Ran Chrome instance on Docker Engine Host and specified Container’s IP followed by 8787 (http://172.17.0.3:8787). Server replied with its logon page. However, I didn’t expect it to because its port wasn’t EXPOSEd.
According to the legacy bridge --link documentation:
So what does linking the containers actually do? You’ve learned that a link allows a source container to provide information about itself to a recipient container. In our example, the recipient, web, can access information about the source db. To do this, Docker creates a secure tunnel between the containers that doesn’t need to expose any ports externally on the container; you’ll note when we started the db container we did not use either the -P or -p flags. That’s a big benefit of linking: we don’t need to expose the source container, here the PostgreSQL database, to the network.
When I first read the above I thought the phrase secure tunnel between containers implied that only the link’s recipient container, within the bridge network, could communicate to the link’s source container. Other containers on the bridge network or host itself couldn’t directly address (communicate) with the source container.
However, after reflecting on this post and running though some container networking scenarios, the word network in the phrase: here the PostgreSQL database, to the network. at the paragraph’s tail, doesn’t refer to the default bridge network but to the IP network external to the Docker Engine Host. In other words, the network that Docker Engine is itself considered as a host.
Given this new understanding EXPOSE:
- purely documents (doesn’t enforce) which ports of a container can be mapped to Docker Engine Host’s ports, permitting certain convenience features like -P, -p and
- doesn’t specify the port(s) that Containers must bind to in order to enable communication between other containers.
In other words, containers can freely communicate to one another over any port they wish, without having to declare exposed ports, as long as they haven’t been intentionally isolated.
When I began this post, I wasn’t confident that the understanding arrived at by the post’s end is correct. But now I’m confident that it is but would appreciate someone more knowledgeable to comment, especially if my latest understanding is flawed.