#What’s the Difference Between Exposing and Publishing a Docker Port? – CloudSavvy IT
Table of Contents
“#What’s the Difference Between Exposing and Publishing a Docker Port? – CloudSavvy IT”
Exposed and Published container ports are two different but related concepts in Docker. Exposed ports are defined in your Dockerfile as simple metadata. You must publish them when your container starts if you want to enable outside access.
Exposing a Port
Ports are exposed via EXPOSE
instructions in an image’s Dockerfile:
EXPOSE 80
Exposing a port doesn’t have any immediate effect though. The statement only communicates that the application inside the container listens on port 80
. It does not open that port to the world or explicitly provide access to any other containers.
As an image author, listing ports used by your workload with EXPOSE
helps users configure appropriate port forwarding rules when they start a container. This is particularly important when non-standard ports are used: while a web server can be expected to listen on port 80, users won’t be able to guess the port used by a custom socket server.
Exposed ports are visible when you list your containers with docker ps
. They’ll show up in the PORTS
column, even though they won’t actually be accessible outside the container. This gives you a simple way of checking which ports the software inside a container is listening on.
You can inspect ports exposed by an image without starting a container by using docker inspect
. Substitute your image’s tag or ID instead of demo-image
:
docker inspect --format="{{json .Config.ExposedPorts}}" demo-image
Publishing Ports
Publishing a port makes it accessible from outside the container. It lets you take a port you’ve discovered by an EXPOSE
instruction, then bind a host port to it.
Ports are exposed with the -p
flag for the docker run
command:
docker run -d -p 8080:80 httpd:latest
This command binds port 8080
on your Docker host to 80
inside your new container. Now you can visit http://localhost:8080
to access the container’s port. If you run docker ps
, you’ll see the PORTS
column now shows this mapping. The exposed container port 80
has been published to the host.
The -p
flag can be used without specifying a port to bind to:
docker run -d -p 80 httpd:latest
This variant will bind port 80 in the container to a random port on the host. You can check the port that’s been assigned by running docker ps
.
-p
also supports publishing a port to specific network interfaces:
docker run -d -p 127.0.0.1:8080:80 httpd:latest
Here the container port 80 will only be accessible via port 8080 on the host’s local loopback address. This protects your container from network calls made by your other devices.
Publishing All Exposed Ports
You can start a container with the --publish-all
flag to have Docker automatically publish all the exposed ports listed in the image’s Dockerfile:
docker run -d --publish-all httpd:latest
This will assign random free ports on your host to each exposed port in the container. Use the docker ps
command to see the port assignations that have been made. This simplifies starting a new container from an image that requires several non-standard ports to be opened.
You can combine --publish-all
with explicit -p
mappings. In this case, a mapping created by a -p
flag will override the random port assigned by --publish-all
.
When You Don’t Need to Publish a Port
You only need to publish container ports with -p
if you want to access them from your Docker host or another device on your physical network. Docker networks are the preferred alternative approach for inter-container traffic.
Containers that share a network can always communicate with each other, even if their ports have not been explicitly published.
docker network create demo-network docker run -d --network demo-network --name web web:latest docker run -d --network demo-network --name database database:latest
In this example, the web
container could connect to a MySQL server running on port 3306 in the database
container using the database:3306
address. Docker automatically sets up routing tables for the container names in the network.
Using Port Ranges
Docker can expose and publish entire port ranges when you need to have multiple ports available:
EXPOSE 8000-8100 docker run --publish-all docker run -p 6000-6100:8000-8100
In the first case, --publish-all
will assign 100 random ports on your host and map them into the container’s range. The second form explicitly binds a host range to a container range as normal. Performance can be impacted if you use a very large number of ports as an iptables
rule will be created for each one.
Summary
Exposed ports are pieces of metadata that define the ports listened to by software inside a container image. The presence of exposed ports doesn’t render them accessible unless you manually publish them. In this sense, the verb “expose” is a misnomer, as many people assume it’s an active action when in fact it’s an informational statement. EXPOSE
should be treated as documentation whereas the -p
flag creates a functioning port mapping.
Docker does provide some extra behavior based on EXPOSE
instructions. You can view a container’s exposed ports with docker ps
irrespective of whether they’ve been published. There’s also the --publish-all
flag that publishes an image’s exposed ports to random host ports.
You only need to publish ports when you want to access a container from outside a Docker network. Communication between containers in the same network is always uninhibited, whether or not the ports involved have been exposed or published.
If you liked the article, do not forget to share it with your friends. Follow us on Google News too, click on the star and choose us from your favorites.
For forums sites go to Forum.BuradaBiliyorum.Com
If you want to read more like this article, you can visit our Technology category.