When you spin up Docker containers, there are generally two types of communication that you want to configure. That is communicationย betweenย containers and communicationย from the outside. Docker allows you to expose docker ports in a couple of different ways for each of these use cases. Letโs take a look at what you need to know to expose a port or multiple ports to your Docker containers.
What Does Docker Expose Port Mean?
When you โexposeโ a port or multiple ports, it means that you are making that network port on aย Docker container availableย to be connected to from either the Docker network or the outside world. By default, Docker containers are isolated in the way their networking is designed and are not accessible unless you configure this.
Isolation helps with security as if a port doesnโt need to be exposed to the outside, it shouldnโt be. And, if you can limit the number of network ports you expose, the better off you will be from an attack surface. However, the downside is that you will need to think about which ports need to be open for necessary or expected communication with your containers.
How to Expose Ports in Docker
Letโs take a look at how to expose ports in Docker and see what commands are needed for opening a Docker port.
To expose ports in Docker, you use the docker run command with theย -p or โpublish flagย for publish ports functionality. This flag specifies which ports are available for connection. Letโs look at a simple example of exposing port 80 on an Nginx Docker image web server using port 8080 on the outside.
docker run -d -p 8080:80 nginx
In this command,ย 8080 is the host port, andย 80 is the container port. The -d flag runs the container inย detachedย mode which is how you want to run containers to keep them running without having to have a console connection to your Docker container host.
The port expose configuration via a port number means that you are exposing the container on the same network internally to the Docker network. By default when you spin up a new container and donโt specify the container network, they are connected to the default bridge network on the Docker host.
Configuring container ports to listen
Whenย creating a Docker containerย from a docker container image, configuring container ports that you want the container to listen on is an important step. To do this, we use a special instruction calledย EXPOSEย in the Dockerfile. For example letโs look at what expose instructions for ports 80 and 443 would look like. Pretty simple:
EXPOSE 80 EXPOSE 443
This EXPOSE instruction tells Docker that the container should expose multiple ports, 80 and 443.
Do you have to do this necessarily? No, if the container image already is exposing the ports, then the configuration will have this by default and you wonโt have to โre-exposeโ the port in your Docker directives.
Case in point, if you see the below, you can see the portย 81/tcpย is being exposed on the container, but you donโt see a host side port mapping.
In addition, the Docker Compose code for the container above (Nginx Proxy Manager) looks like the following, so you donโt see any directives on the ports side or an expose directive for port 81. So, it means the container image is already exposing this port and the container listens on this exposed port by default.
Docker Container Port Mapping
Letโs look at the Docker container port mapping construct. This is the configuration that allows mapping internal container ports to external host ports. When you do this, it allows traffic that is destined for the host IP network interface to be forwarded inward to the container and vice versa.
docker run -d -p 5000:5000 testapp
This command mapsย port 5000 on the host to port 5000 on the container. This configures communication to the containerโs ports via the host IP address and makes the container accessible by the host system. Otherwise, you wouldnโt be able to communicate with it.
Configuring the exposed Ports with Docker Compose
Docker Compose is the means by which you can spin up Docker container โstacksโ that allow multiple containers to be provisioned at once. This is a great way to work with Docker containers if you have an application that requires multiple containers as part of the overall application architecture.
Docker Compose uses YAML code to describe the container configuration. Theย portsย directive configures published ports available for connection from the host into the container.
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
In this configuration, the web service exposes port 80 of the container on port 8080 of the host machine.
Verifying Exposed Ports with Docker PS and Docker-Compose PS
When you provision a container, you can verify the exposed port mappings using theย docker psย command.
docker ps
Look for the PORTS column in the output to see the mappings
When you useย docker-compose psย command, it shows the same information, just for the application stack configured via the Docker Compose file:
Troubleshooting Docker expose port mappings
There are a few issues that could come up when you are trying to expose a specified port for a container. Note the following:
- Make sure the port is not in use by another container
- Make sure the container is attached to the Docker network that you assume it is connected to
- Is the port mapped to the host port you expect?
- If you are just exposing a port to use with something like Nginx Proxy Manager, make sure the port proxy is configured corrected to forward traffic to the internally exposed ports of the Docker container.
Best Practices for Exposing Ports
- Use Non-Standard Ports:ย Common ports like 80 and 443 are going to be widely used, so you can use non-standard ports to avoid conflicts
- Limit Exposed Ports:ย Only expose Docker container ports as this will help to avoid security vulnerabilities by only exposing what is absolutely needed
- Document Exposed Ports:ย Maintain clear documentation of which ports are exposed and their purposes.