Docker – Difference between port expose and port publish


Quite a lot of people who start to learn docker seem to have a hard time trying to grasp the concept of what port expose (-e) and port publish (-p) mean. I’m writing this blog to explain just that.

The way I remember this is to imagine a container like a computer and a docker stack (the collection of services) like a network of computers with each computer of that network being a container in the stack. We have computer firewalls that are placed in front of each of these imaginary computers and a network firewall that is placed on the network gateway.

Now, with this in mind, we can think of three different possible scenarios:

  1. The traffic originates from inside the computer (Or the traffic originates from inside the container).
  2. The traffic originates from inside the network but outside the container (Or the traffic originates from one container to another inside the same stack).
  3. The traffic originates from outside the network (Or the traffic originates from outside the stack).

For the first scenario, the traffic encounters neither the computer firewall nor the network firewall. Therefore, we neither need to configure the computer firewall nor the network firewall to allow the inbound traffic to pass. In terms of docker, we neither need to expose the port nor need to publish the port. This type of configuration is helpful when write a health check script that queries the service and based upon the received response, either kills or restarts the service.

The second scenario is when the traffic does not encounter the network firewall but hits the computer firewall as soon as it approaches the target computer. To successfully serve such requests, we need to configure the computer firewall to allow the inbound traffic but, can optionally leave the network firewall closed. The computer firewall allows the traffic when you expose the port. This configuration is helpful for cases where you want your service to be accessible from inside the network only. For example, a database that interacts with the business-logic tier of your application but, should not be exposed to the open internet.

Remember, if you start your container as docker run -e PORT=8080 <container-id> you won’t get anything on localhost:8080 because localhost and the network on which docker containers are deployed are two different networks. You can confirm this fact by listing out the networks on your machine (docker node) using ifconfig command on Linux or ipconfig on Windows.

But, what if we need to allow external users to be able to access our applications? This is where a user from another network tries to access our application but hits the barrier created by the network firewall. Now, that is exactly what our third scenario is. This network firewall can be opened using port publish. When you expose and publish your port, the service listening on the network can be accessed not only from computers on the same network (containers in the same stack) but, also from outside the network. This configuration is used for services with which the users interact. For example, the user-interface layer of your applications.


Leave a Reply