Difference between “expose” and “publish” in docker
I’m experimenting with Dockerfiles, and I think I understand most of the logic. However, I don’t see the difference between “exposing” and “publishing” a port in this context.
All the tutorials I have seen first include the
EXPOSE command in the Dockerfile:
... EXPOSE 8080 ...
They then build an image from this Dockerfile:
$ docker build -t an_image - < Dockerfile
And then publish the same port as above when running the image:
$ docker run -d -p 8080 an_image
or publish all ports using
$ docker run -d -P an_image
What is the point of exposing a port in the Dockerfile, if it will be published anyway? Would there ever be a need to expose a port first, and not publish it later? Effectively, I would like to specify all the ports that I will use in the Dockerfile when creating the image, and then not bother with them again, running them simply with:
$ docker run -d an_image
Is this possible?
2 Solutions collect form web for “Difference between “expose” and “publish” in docker”
Basically, you have three options:
- Neither specify
- Only specify
If you do not specify any of those, the service in the container will not be accessible from anywhere except from inside the container itself.
EXPOSE a port, the service in the container is not accessible from outside Docker, but from inside other Docker containers. So this is good for inter-container communication.
-p a port, the service in the container is accessible from anywhere, even outside Docker.
The reason why both are separated is IMHO because
- choosing a host port depends on the host and hence does not belong to the Dockerfile (otherwise it would be depending on the host),
- and often it’s enough if a service in a container is accessible from other containers.
The documentation explicitly states:
EXPOSEinstruction exposes ports for use within links.
It also points you to how to link containers, which basically is the inter-container communication I talked about.
PS: If you do
-p, but do not
EXPOSE, Docker does an implicit
EXPOSE. This is because if a port is open to the public, it is automatically also open to other Docker containers. Hence
EXPOSE. That’s why I didn’t list it above as a fourth case.
EXPOSE allow you to define private (container) and public (host) ports to expose at image build time for when the container is running.
The public port is optional, if not a public port is specified, a random port will be selected on host by docker to expose the specified container port on Dockerfile.
A good pratice is do not specify public port, because it limits only one container per host ( a second container will throw a port already in use ).
You can use
docker run to control what public port the exposed container ports will be connectable.
Anyway, If you do not use
-p, no ports will be exposed.
If you always use
docker run you do not need
EXPOSE but if you use
docker run command may be more simple,
EXPOSE can be useful if you don’t care what port will be expose on host, or if you are sure of only one container will be loaded.