Home > Back-end >  container port mapping concept confusion
container port mapping concept confusion

Time:11-13

I know I can map host port to container port in Docker command or in Dockerfile or in docker-compose.yml. I have no problem there, I know how to do that too.

For example, I have the following container:

$ docker container ls
ID    COMMAND                      PORTS
84..  "python app.py"              0.0.0.0:5000->5000/tcp

I know it means the host port 5000 is mapped to container port 5000.

My question is only on the 0.0.0.0 part. I have done some study, it is said that 0.0.0.0:5000 means map port 5000 of all interfaces on host.

I understand the 5000 port on host, but I don't get "all interfaces on host", what does it mean exactly? Could someone please elaborate for me? Does it mean all network interfaces on the host? What "all interface" this "0.0.0.0" refers to exactly?

CodePudding user response:

Your physical hardware can have more than one network interface. In this day and age you likely have a wireless Ethernet connection, but you could also have a wired Ethernet connection, or more than one of them, or some kind of other network connection. On a Linux host if you run ifconfig you will likely have at least two interfaces, your "real" network connection and a special "loopback" connection that only reaches the host. (And this is true inside a container as well, except that the "loopback" interface only reaches the container.)

When you set up a network listener, using the low-level bind(2) call or any higher-level wrapper, you specify not just the port you're listening on but also the specific IP address. If you listen on 127.0.0.1, your process will be only reachable from the loopback interface, but not off-box. If you have, say, two network connections where one connects to an external network and one an internal one, you can specify the IP address of the internal network and have a service that's not accessible from the outside world.

This is where 0.0.0.0 comes in. It's possible to write code that scans all of the network interfaces and separately listens to all of them, but 0.0.0.0 is a shorthand that means "all interfaces".

In Docker, this comes up in three ways:

  1. The default -p listen address is 0.0.0.0. On a typical developer system, you might want to explicitly specify -p 127.0.0.1:8080:8080 to only have your service accessible from the physical host.

  2. If you do have a multi-homed system, you can use -p 10.20.30.40:80:8080 to publish a port on only one network interface.

  3. Within a container, the main container process generally must listen to 0.0.0.0. Since each container has its own private localhost, listening on 127.0.0.1 (a frequent default for development servers) means the process won't be accessible from other containers or via docker run -p.

  • Related