Docker compose bridge networking
Docker Compose is an easy way for deploying multi-container applications. It automates a lot of the booking keeping, networking, and resource management of applications in a single neat docker-compose.yml file. we can get the app up by running docker-compose up and turn it back down using docker-compose down.
A lot gets added to our Docker environment, that gets overlooked and then deleted with the last command. One of the most important objects is a Bridge network
Docker Bridge Network
create a new Docker Network called my-network and inspect it, run:
# docker network create -d bridge my-network
fd524d2fa9f23d6f801eb88bbbde9e0582fde7e83bc93df12b85331ef934c98b
# docker inspect my-network
[
{
"Name": "my-network",
"Id": "fd524d2fa9f23d6f801eb88bbbde9e0582fde7e83bc93df12b85331ef934c98b",
"Created": "2021-04-29T05:27:40.979436747-04:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
Any container that gets connected to this network will get an IP in the range of 172.18.0.3 to 172.18.255.254. Let’s try creating a couple of containers on this network.
# docker run -dit --name container1 --network my-network ubuntu:latest
# docker run -dit --name container2 --network my-network ubuntu:latest
If we run, docker inspect my-network we will notice that individual containers with their proper name and corresponding IP addresses show up in the containers field of the JSON output
# docker inspect my-network
[
"ConfigOnly": false,
"Containers": {
"565a223c73aff3ac635822d7180ec381c6820aa7e02f43321d6e4436c6b626a9": {
"Name": "container2",
"EndpointID": "0ae75308b374fdf721c4113e64e967d5eb4484945f026986d0112166d8d87902",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"b553dd356230ccd207f68853d9147ee8d711472817aa42195209d4ee21d52442": {
"Name": "container1",
"EndpointID": "4deddd84b5139f2bbb0619af2aa13e2f8652e762b29b5e883f09238614635071",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
If we create another network my-network2, it will have a different subnet mask like 172.19.0.0/16, and containers on it will be isolated from containers on other networks. So, ideally, we want one network per application, so every app is secure and isolated from one another.
Compose Creates a Network
Docker Compose understands the idea behind running services for one application on one network. When we deploy an app using the Docker Compose file, even when there’s no mention of specific networking parameters, Docker Compose will create a new bridge network and deploy the container over that network.
If the docker-compose.yml is in the directory my-app, the directory’s name will be used to name the network as well as the containers mounted on top of it.
# mkdir my-app
# cd my-app/
# cat docker-compose.yml
version: '3'
services:
my-nginx:
image: nginx:latest
we didn’t expose any ports. Let’s deploy this app
#docker-compose up -d
This creates a new network called my-app_default using bridge network driver. we can list all the networks on your personal setup using docker network ls and then pick the network interface that matches our directory’s name.
If we create another container, using directly the CLI.on this network, we can actually talk to our my-nginx service
# docker run -dit --name container4 --network my-app_default ubuntu:latest
53a46e6f0d6b48e4705be7313b67c6262be246f3d303c5575b19f8ce413c041c
# docker exec -it container4 bash
# curl http://my-app_my-nginx_1
This will print an html file with familiar snippets like “Welcome to Nginx” visible in it. The nginx web server is reachable from within the network without us having to publish any ports.
When running a database and connecting it to the frontend, we won’t have to publish the Database port at all. Instead, you can reach the DB from the webserver just by calling its predictable hostname. Even when docker-compose is run elsewhere where and the IP and the subnet may now differ, the containers will still be able to talk to one another.
To publish a port to the outside world we would write something like the following
#cat docker.yml
version: '3'
services:
my-nginx:
image: nginx:latest
port:
- “8080:80”
we can access the webserver from port 8080 at the IP of our Docker Host. This can be, for example, the public IP of our VPS or just localhost if we are running Docker on our desktop. Yet again, we don’t have to expose any ports for our database container, because the webserver can talk to it directly and thus this reduces the risk of databases exposed to the Internet.
# docker-compose down
This custom bridge network along with all the containers that were created and attached on top of it, using the docker-compose.yml file, will get deleted. Leaving our Docker environment in a clean state.
Defining your own network
Compose allows defining our own network definition. This would include options for the subnet mask, IPv6 addresses, among other things. The way it is done is that we have top-level networks just like services or versions are top-level keys. This key has no indentation. Under the network's key, we can now define various attributes of the network, for now, we will keep it simple and just mention that it ought to use a bridge driver.
# cat docker-bridge.yml
version: '3'
services:
my-nginx:
image: nginx:latest
networks:
- my-network
networks:
my-network:
driver: bridge
The order in which the network is defined and then used inside a service definition is relevant. So the whole yaml file will look something like this.
Kyle Jacobs says:
Great Article