Skip to main content
Docker

Port Mapping in Docker: When and How to Use it?

Understand the advantages of using port mapping in Docker and learn various ways of doing it.

Umair Khurshid

Warp Terminal

Port management in Docker and Docker Compose is essential to properly expose containerized services to the outside world, both in development and production environments.

Understanding how port mapping works helps avoid conflicts, ensures security, and improves network configuration.

This tutorial will walk you understand how to configure and map ports effectively in Docker and Docker Compose.

What is port mapping in Docker?

Port mapping exposes network services running inside a container to the host, to other containers on the same host, or to other hosts and network devices. It allows you to map a specific port from the host system to a port on the container, making the service accessible from outside the container.

In the schematic below, there are two separate services running in two containers and both use port 80. Now, their ports are mapped with hosts port 8080 and 8090 and thus they are accessible from outside using these two ports.

Docker port mapping example

How to map ports in Docker

Typically, a running container has its own isolated network namespace with its own IP address. By default, containers can communicate with each other and with the host system, but external network access is not automatically enabled.

Port mapping is used to create communication between the container's isolated network and the host system's network.

For example, let's map Nginx to port 80:

docker run -d --publish 8080:80 nginx

The --publish command (usually shortened to -p) is what allows us to create that association between the local port (8080) and the port of interest to us in the container (80).

In this case, to access it, you simply use a web browser and access http://localhost:8080

On the other hand, if the image you are using to create the container has made good use of the EXPOSE instructions, you can use the command in this other way:

docker run -d --publish-all hello-world

Docker takes care of choosing a random port (instead of the port 80 or other specified ports) on your machine to map with those specified in the Dockerfile:

Mapping ports with Docker Compose

Docker Compose allows you to define container configurations in a docker-compose.yml. To map ports, you use the ports YAML directive.

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"

In this example, as in the previous case, the Nginx container will expose port 80 on the host's port 8080.

Port mapping vs. exposing

It is important not to confuse the use of portswith expose directives. The former creates a true port forwarding to the outside. The latter only serves to document that an internal port is being used by the container, but does not create any exposure to the host.

services:
  app:
    image: myapp
    expose:
      - "3000"

In this example, port 3000 will only be accessible from other containers in the same Docker network, but not from outside.

Mapping Multiple Ports

You just saw how to map a single port, but Docker also allows you to map more than one port at a time. This is useful when your container needs to expose multiple services on different ports.

Let's configure a nginx server to work in a dual stack environment:

docker run -p 8080:80 -p 443:443 nginx

Now the server to listen for both HTTP traffic on port 8080, mapped to port 80 inside the container and HTTPS traffic on port 443, mapped to port 443 inside the container.

Specifying host IP address for port binding

By default, Docker binds container ports to all available IP addresses on the host machine. If you need to bind a port to a specific IP address on the host, you can specify that IP in the command. This is useful when you have multiple network interfaces or want to restrict access to specific IPs.

docker run -p 192.168.1.100:8080:80 nginx

This command binds port 8080 on the specific IP address 192.168.1.100 to port 80 inside the container.

Port range mapping

Sometimes, you may need to map a range of ports instead of a single port. Docker allows this by specifying a range for both the host and container ports. For example,

docker run -p 5000-5100:5000-5100 nginx

This command maps a range of ports from 5000 to 5100 on the host to the same range inside the container. This is particularly useful when running services that need multiple ports, like a cluster of servers or applications with several endpoints.

Using different ports for host and container

In situations where you need to avoid conflicts, security concerns, or manage different environments, you may want to map different port numbers between the host machine and the container. This can be useful if the container uses a default port, but you want to expose it on a different port on the host to avoid conflicts.

docker run -p 8081:80 nginx

This command maps port 8081 on the host to port 80 inside the container. Here, the container is still running its web server on port 80, but it is exposed on port 8081 on the host machine.

Binding to UDP ports (if you need that)

By default, Docker maps TCP ports. However, you can also map UDP ports if your application uses UDP. This is common for protocols and applications that require low latency, real-time communication, or broadcast-based communication.

For example, DNS uses UDP for query and response communication due to its speed and low overhead. If you are running a DNS server inside a Docker container, you would need to map UDP ports.

docker run -p 53:53/udp ubuntu/bind9

Here this command maps UDP port 53 on the host to UDP port 53 inside the container.

Inspecting and verifying port mapping

Once you have set up port mapping, you may want to verify that it’s working as expected. Docker provides several tools for inspecting and troubleshooting port mappings.

To list all active containers and see their port mappings, use the docker ps command. The output includes a PORTS column that shows the mapping between the host and container ports.

docker ps

This might output something like:

inspecting and verifying port mapping in Docker

If you more detailed information about a container's port mappings, you can use docker inspect. This command gives you a JSON output with detailed information about the container's configuration.

docker inspect <container_id> | grep "Host"

This command will display the port mappings, such as:

Wrapping Up

Learn Docker: Complete Beginner’s Course
Learn Docker, an important skill to have for any DevOps and modern sysadmin. Learn all the essentials of Docker in this series.

When you are first learning Docker, one of the more tricky topics is often networking and port mapping. I hope this rundown has helped clarify how port mapping works and how you can effectively use it to connect your containers to the outside world and orchestrate services across different environments.

Umair Khurshid