How to Establish Communication Between Containers and the Host Machine

Cesar Diaz
May 7, 2020

Docker is great. We all know containers help simplify and automate the development and setup of an application environment. Let's explore how we can establish communication between containers and from the inside to the host machine.

First of all, we'll provide a little context. To understand how the process of communication works, we'll need to clarify some concepts first.

Docker Network

When you list the networks after a traditional installation of Docker and run the following command docker network ls...

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
dbb52b9c258f        bridge              bridge              local
0c35ae96fe77        host                host                local
cb85dfadb376        local_default       bridge              local
94431f37b012        none                null                local

...you might get the default in-built networks:

  • Bridge
  • Host
  • None

Note: As you probably noticed, there is another one called local_default, which in this case is a user-defined bridge network.

A brief overview extracted from the current Docker documentation states:

Bridge network: The default network driver. If you don’t specify a driver, this is the type of network you are creating. Bridge networks are usually used when your applications run in standalone containers that need to communicate

Host network: Adds a container on the host’s network stack. As far as the network is concerned, there is no isolation between the host machine and the container. For instance, if you run a container that runs a web server on port 80 using host networking, the web server is available on port 80 of the host machine.

None network: Is generally known as container specific network. A container can be attached to a none network. This allows internal communication between containers that are isolated to outside networks. 1

Therefore, the network in charge of the communication process between containers is by default the bridge network or the user-defined bridge networks, so let’s focus on this type of network.

Bridge Networks

$ ifconfig bridge0
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
  options=63<RXCSUM,TXCSUM,TSO4,TSO6>
  ether 82:17:02:be:ed:00
  Configuration:
    id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
    maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
    root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
    ipfilter disabled flags 0x2
  member: en1 flags=3<LEARNING,DISCOVER>
          ifmaxaddr 0 port 5 priority 0 path cost 0
  member: en2 flags=3<LEARNING,DISCOVER>
          ifmaxaddr 0 port 6 priority 0 path cost 0
  Address cache:
  nd6 options=201<PERFORMNUD,DAD>
  media: <unknown type>
  status: inactive

When you start Docker, a default bridge network (also called bridge0 or docker0) is created automatically, and newly-started containers connect to it unless otherwise specified. You can also create user-defined custom bridge networks. User-defined bridge networks are superior to the default bridge network.

In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network. The Docker bridge driver automatically installs rules in the host machine so that containers on different bridge networks cannot communicate directly with each other.

The communication would be established only if the bridge network is provided and the proper permissions on the iptables rules are given.

Ping Between Containers

To understand the communication between containers, let’s create two containers over the same network and make sure that they can see each other using a ping command.

  • Create two containers.
$ docker run -d --name nginx1  -p 8001:80 nginx:latest
$ docker run -d --name nginx2  -p 8002:80 nginx:latest
  • Create a custom network.
$ docker network create my-custom-net
$ docker network inspect my-custom-net
  • List the networks. You should see a new network type bridge created.
$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
dbb52b9c258f        bridge              bridge              local
0c35ae96fe77        host                host                local
cb85dfadb376        my-custom-net       bridge              local
94431f37b012        none                null                local
  • Connect the network with the containers.

docker network connect my-custom-net nginx1

docker network connect my-custom-net nginx2

  • Inspect the network. You should see the containers attached to the network.
$ docker network inspect my-custom-net
[
    {
        "Name": "my-custom-net",
        "Id": "cb85dfadb376cc7aa020410ee6c839137b6d5dedff7972b9eed0e37ec573b002",
        "Created": "2020-04-09T20:26:42.897203Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
  • Before you try to make the ping, you should install iputils-ping in the container to make it work. So we enter into the container named nginx1.
$ docker exec -ti nginx1 bash
root@39484307e6ee:/# apt update
root@39484307e6ee:/# apt install iputils-ping
  • You’re ready to run a ping command.
docker exec -ti nginx1 ping nginx2
PING nginx2 (172.18.0.3) 56(84) bytes of data.
64 bytes from nginx2.my-custom-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.224 ms
64 bytes from nginx2.my-custom-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.093 ms
64 bytes from nginx2.my-custom-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.082 ms
64 bytes from nginx2.my-custom-net (172.18.0.3): icmp_seq=4 ttl=64 time=0.081 ms

Connecting the Container to a Service Inside the Host

Docker allows you to have access to the host from the containers through a special DNS named host.docker.internal.

You can run ping inside the container nginx1. You will get a response with your current host IP

root@39484307e6ee:/# ping host.docker.internal


In a nutshell, we achieved a better understanding of how bridge networks in Docker make communication easier between containers in the same network. If required, we can connect our containers to any service on our host using the special host.docker.internal.


  1. "Networking overview," Docker Docs. 

"How to Establish Communication Between Containers and the Host Machine" by Cesar Diaz is licensed under CC BY SA. Source code examples are licensed under MIT.

Photo by Miryam León.

Categorized under research & learning.

Join our team

If you're passionate about building quality software and our values resonate with you, get in touch with us!