Running SQL containers on the default network - dbafromthecold/SqlServerAndContainersGuide GitHub Wiki

By default, docker provides a default bridge network that we deploy containers on when we don't specify any network in our container run statement: -

docker container run -d `
--publish 15789:1433 `
--env ACCEPT_EULA=Y `
--env SA_PASSWORD=Testing1122 `
--name sqlcontainer1 `
mcr.microsoft.com/mssql/server:2019-CU5-ubuntu-18.04

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/1.RunAContainer.png

We can view the networks available to us by running: -

docker network ls

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/2.ListNetworks.png

  1. bridge - the default network. In Docker, a bridge network is a software bridge that allows all containers connected to it to communicate.
  2. host - removes network isolation between the container and the host, aka use the host's network directly.
  3. none - disables the containers networking stack. Useful for running very isolated containers.

If we inspect the default bridge network we can see our container attached to it: -

docker network inspect bridge

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/3.InspectBridgeNetwork.png

All containers on the default bridge network can communicate via their IP address. Let's blow that first container away: -

docker container rm sqlcontainer1 -f

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/4.DeleteContainer.png

And spin up another two containers with ping installed (this is a custom image running SQL Server 2019 with ping installed): -

docker container run -d `
--env ACCEPT_EULA=Y `
--env MSSQL_SA_PASSWORD=Testing1122 `
--name sqlcontainer2 `
ghcr.io/dbafromthecold/customsql2019-tools:cu5

docker container run -d `
--env ACCEPT_EULA=Y `
--env MSSQL_SA_PASSWORD=Testing1122 `
--name sqlcontainer3 `
ghcr.io/dbafromthecold/customsql2019-tools:cu5

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/5.RunTwoOtherContainers.png

N.B. - Notice that we haven't specified the --publish flag for either of these containers! So we can't connect to SQL via localhost,PORTNUMBER, we would have to use the container's IP addresses.

Let's have a look at the bridge network again: -

docker network inspect bridge

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/6.InspectBridgeNetworkAgain.png

And there we can see our two containers, with their IP addresses.

We can grab the IP addresses directly with: -

 docker inspect sqlcontainer2 --format '{{ .NetworkSettings.IPAddress }}'
 docker inspect sqlcontainer3 --format '{{ .NetworkSettings.IPAddress }}'

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/7.GetContainerIpAddresses.png

Cool. Let's test communication between the two containers: -

 docker exec sqlcontainer2 ping 172.17.0.3 -c 4
 docker exec sqlcontainer2 ping 172.17.0.2 -c 4

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/8.PingContainers.png

That works! But referencing the container by name doesn't: -

docker exec sqlcontainer2 ping sqlcontainer3 -c 4

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/9.PingContainerByName.png

The default bridge network doesn't allow for DNS resolution of container names to IP addresses.

There is an option we can use to get around this though. Let's blow those containers away: -

docker rm sqlcontainer2 sqlcontainer3 -f

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/10.DeleteContainers.png

And spin up two new containers, using the --add-host flag: -

docker container run -d `
--env ACCEPT_EULA=Y `
--env MSSQL_SA_PASSWORD=Testing1122 `
--add-host=sqlcontainer5:172.17.0.3 `
--name sqlcontainer4 `
ghcr.io/dbafromthecold/customsql2019-tools:cu5

docker container run -d `
--env ACCEPT_EULA=Y `
--env MSSQL_SA_PASSWORD=Testing1122 `
--add-host=sqlcontainer4:172.17.0.2 `
--name sqlcontainer5 `
ghcr.io/dbafromthecold/customsql2019-tools:cu5

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/11.RunTwoMoreContainers.png

What this does is add an entry into the container host file. We can check that by running: -

docker exec sqlcontainer4 cat /etc/hosts
docker exec sqlcontainer5 cat /etc/hosts

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/12.ViewHostsFile.png

And there we see an entry for the other container in each. So that means we can now reference the other container by name: -

docker exec sqlcontainer4 ping sqlcontainer5 -c 4
docker exec sqlcontainer5 ping sqlcontainer4 -c 4

/images/5.ContainerNetworking/RunningContainersOnDefaultNetwork/13.PingContainersByName.png

Ok, that does mean that we would need to know the IP address of the containers in order to add it to our container run statement.

If we wanted to have DNS resolution of container name to IP addresses automatically, we would need to a custom network.