Docker Networking allows you to get containers communicating with eachother and the host machine. For example you may want your application container to be accessable to the host machine on port 80, as well as be able to communicate with a database container which can not be accessed from the host machine. When modifying network, docker is managing the underlying network infrastructure such as iptables.

Docker network types:

The default bridge does not automatically open all ports to other containers in the network, they have to be manually opened. The user defined bridge automatically exposes all ports to each other, and no ports to the host machine.

Containers on the same bridge network can communicate with eachother but can't communicate with containers on different bridge networks or different hosts. So in the example above container 1 and 2 can communicate with eachother but neither can communicate to container 3 or to anything outside of the docker host.

In order for containers to communicate outside of the Docker host they need to publish their port to the host machine. The command "docker run --publish 8080:80 5a83" will expose port 80 of the container to the outside as port 8080. Therefor you could vist http://192.168.1.16:8080 or http://localhost:8080 but your application in the container runs on port 80.

This means an application which runs on port 80 can be spun up multiple times on different ports.

The default bride network has a --link option to link containers together, but we wont cover that since creating your own network is recommended.

View docker networks

Use the below command to vew existing networks. Docker automatically creates 3 networks: bridge, none and host. The bridge network is the default for all containers.

> docker network ls

You can view more specific details about a network by inspecting it.

> docker network inspect bridge

IPAM.Config.Gateway is the IP address between the Docker host and the bridge network.

Containers.{id}.IPv4Address is the IP address of the container.

collapse
Create network

We will be creating a user defined bridge network. We can specifiy that with --driver bridge but it is not required since bridge is the default when creating.

> docker network create --driver bridge mynetwork

Once you have created your network run "docker network ls" and "docker network inspect mynetwork". Notice on inspection there are no containers connected.

collapse
Remove network

Let's try remove the network. Then add it back afterwards

> docker network rm mynetwork

Once you have removed your network run "docker network ls" to see that has gone. Create it again for the next few steps.

remove all networks

The following will remove all networks not used by any containers.

> docker network prune

collapse
Connect container to network

You can connect to a network on container creation. Note: this container will not be part of the default brdige.

> docker run --network mynetwork --name my-nginx --publish 8080:80 nginx

If you have a running container you can connect it to a network. Note: this container will be connected to both networks.

> docker network connect my-net my-container

Once you have connected containeres to your network run "docker network inspect mynetwork" and "docker network inspect bridge".

collapse
Disconnect container from network

> docker network disconnect mynetwork my-nginx

Once you have removed your network run "docker network ls" to see that it has gone. Create it again for the next few steps.

collapse
Network alias

You can communicate with a container via the network with the containers name. The problem is that name has to be unique therefore if the named container goes down then there is no back up. Instead you can give multiple containers an alias name and communicate with them via that alias, so that if one container is not reachable there are others up with that name.

> docker run --name myaliascontainer --network mynetwork --net-alias myalias nginx

> docker container inspect myaliascontainer

When you inspect the running container, find Networks.mynet.Aliases you will see the alias name 'myalias'

collapse

Check your current networks:

> docker network ls

Create a new network and check it:

> docker network create --driver bridge mynet

> docker network ls

> docker network inspect mynet

Create two containers and add them to your new network and check it:

> docker run -itd --name a1 --network mynet alpine ash

> docker run -itd --name a2 --network mynet alpine ash

> docker container ls

> docker network inspect mynet

You should find two containers running and in the network inspect you should see they are both connected to mynet.

-itd: d detaches the running container from the console, i makes the container interactive so that you can type commands into the conttainer, t is TTY which shows the input and output from the container.

Attach to a container an enter its command line:

> docker attach a1

Ping google to check that the container can reach the internet:

# ping -c 2 google.com

Ping the ip address of your second container, then try ping the name of the second container:

# ping -c 2 172.18.0.3

# ping -c 2 a2

ctrl+p ctrl+q

Being able to detect the container by the name is called automatic service discovery.

Remember, with the default the bridge network you can not ping by container name. You have to use the user defined bridge.

NOTE: Since the IP address of a container may change each time a new instance is created, dont rely on it, rather refer to the container by name.

Check out these links for more info:

My Docker Samples