Search code examples
dockernetworkingcontainersbridge

Docker Network : Call between 2 container with "localhost"


On our docker instance, we have two containers A and B in the same MY_NETWORK docker network in bridge mode. From container A, we call container B using the url "localhost: xxxx". We are surprised because it works despite that localhost only concerns the container in which it is called.

We would like to understand how this is possible because from our vision, localhost concerns the container itself and not another container of the same docker network?

Do you have an idea ?


Solution

  • What you claiming is a weird behavior, I have demonstrate a testcase to insure that this is not supposed to happen I have implemented the network bridge just as you did and assign 2 containers to it one is nginx container which will act as the server and the other is alpine container which will act as the client.

    docker network create --driver=bridge --subnet=10.10.2.0/24 dedicated
    docker run -it -p 40000:80 --network=dedicated nginx sh
    docker run -it -p 49001:30000 --network=dedicated alpine sh
    

    If we tried to inspect the network using docker network inspect command we would make sure that everything is aright

    [
    {
        "Name": "dedicated",
        ...
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.10.2.0/24"
                }
            ]
        },
      ...
        "Containers": {
            "2380d57bb0158792531b3d38dde5cecb3e77e96db7c147c0a0f458a895996767": {
                "Name": "amazing_snyder",
                "EndpointID": "83b9ed340f855aae2b6aa76e47546713583657af1090a63f9ddfa2d533036f5a",
                "MacAddress": "02:42:0a:0a:02:02",
                "IPv4Address": "10.10.2.2/24",
                "IPv6Address": ""
            },
            "2506c5bfdac621ff9e88d1594438914ad61acdb38870b7960a34c90412aac13a": {
                "Name": "happy_galois",
                "EndpointID": "b366f502cf48e39e96815bfd0b7ba29f57bea46ec56ee0651dff64e8197ce5c3",
                "MacAddress": "02:42:0a:0a:02:03",
                "IPv4Address": "10.10.2.3/24",
                "IPv6Address": ""
            }
        },
       ...
    }
    ]
    

    Now let's play a bit, I will use curl and routetrace to figure out wither we will reach the other server throw localhost or not

    Curl Test using localhost

    / # curl localhost:80
    curl: (7) Failed to connect to localhost port 80: Connection refused
    

    If we also tried the exposed port it would fail

    / # curl localhost:40000
    curl: (7) Failed to connect to localhost port 40000: Connection refused
    

    Although if we tried the server ip it will success

    / # curl 10.10.2.2:80
    <!DOCTYPE html>
    ....
    <a href="http://nginx.com/">nginx.com</a>.</p>
    <p><em>Thank you for using nginx.</em></p>
    ....
    

    To make sure that this is the default behavior i tried to traceroute the localhost:80 and the 10.10.2.2:80 to make sure that the localhost will not traverse throw the network bridge.

    / # traceroute localhost:80
    traceroute to localhost:80 (127.0.0.1), 30 hops max, 46 byte packets
    1  localhost (127.0.0.1)  0.023 ms  0.019 ms  0.016 ms
    

    It never leaved the machine while using the IP it reached the other machine using the network bridge.

    / # traceroute 10.10.2.2:80
    traceroute to 10.10.2.2:80 (10.10.2.2), 30 hops max, 46 byte packets
    1  2380d57bb015.dedicated (10.10.2.2)  0.029 ms  0.023 ms  0.021 ms
    

    I don't know how it worked for you but my best guess is to check your container config and inspect your network that might lead you to something.