In this article, I will discuss some concepts that most tutorials rarely discuss in Docker containerization. So let’s get into the tutorial.
Most people are stuck on the idea of making a connection through the terminal, but it disconnects when you close the terminal, so we need to make the connection in the docker-compose.yml, and from the terminal. The benefit of using a terminal is that you can cross-check whether the container can communicate and verify the network being used.
Real-life Example of Communicating to the external network
I have taken a real example of nextjs app router and Django rest framework dockerization, and I created two separate docker-compose.yml files, but in this case, the bridge network won’t work since it isolates the Docker container from the outside network or even within the container, so it can’t communicate with the Docker container from the outside network unless you create a custom external network.
services:
frontend:
container_name: frontend_container
build:
context: .
dockerfile: Dockerfile
image: frontend-img
ports:
- "3000:3000"
networks:
- frontend
networks:
frontend:
external: true
name: custom_network
Just like I have created a custom_network. Which I can identify while running
docker network ls
Here is the output:-
C:\Users\CodewithDev>docker network ls
NETWORK ID NAME DRIVER SCOPE
01cae74bfc4c bridge bridge local
34e6d4067150 custom_network bridge local
0c1138bda19e host host local
0b28bf0c69e4 none null local
C:\Users\CodewithDev>
It will list all the networks, then let’s inspect the custom_network.
If we inspect the custom network, we will see frontend_container, which means I can now fetch blog posts from the Django REST Framework backend since I set the external network as custom_network.
C:\Users\CodewithDev>docker network inspect custom_network
[
{
"Name": "custom_network",
"Id": "34e6d4067150bf214d806e123f2901af1c7ac515162e3240ce37c5c24655916e",
"Created": "2026-05-06T07:30:09.855048776Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"IPRange": "",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Options": {
"com.docker.network.enable_ipv4": "true",
"com.docker.network.enable_ipv6": "false"
},
"Labels": {},
"Containers": {
"1d1da8a799c2ff20f27ebe3a7ac2e91f6cacd4f801d70bbb2b2434a3e8aefbbb": {
"Name": "celery_container",
"EndpointID": "4bc40c83581d46ea316862449ec91a5430367814463871bbecfbd92c48dafe34",
"MacAddress": "e2:ac:cc:a9:f4:7b",
"IPv4Address": "172.18.0.7/16",
"IPv6Address": ""
},
"248a69f6ada00727f62392f7a0c8fb1f3eaa5cb6b11aeb89d6f154b53ca8aa3d": {
"Name": "django_container",
"EndpointID": "612b7b3b86bceeac83b132ac7d3fd93e20ffe6bdaff71f1ae30ad587de543621",
"MacAddress": "26:60:3e:23:4d:44",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
},
"46fbda061d78516b9544e88bab899fa5a8edd0755eff92e7d3ddeff40975b865": {
"Name": "frontend_container",
"EndpointID": "3e27e396d5dd937f06fd1df841c86020c4587d25f924d0a6673c500d04a0ed28",
"MacAddress": "02:bd:85:4e:04:ea",
"IPv4Address": "172.18.0.5/16",
"IPv6Address": ""
},
"8f76a7710f14a345497adf376b7d062f4a0e3786d1007e6185957941a9030597": {
"Name": "celery_beat_container",
"EndpointID": "ca6763da7562e18303c7a016c949c4fc8665eb60a4ae4c8637403dbcd2013954",
"MacAddress": "3e:c5:e0:c0:e2:21",
"IPv4Address": "172.18.0.6/16",
"IPv6Address": ""
},
"e68c877f3befe4a83a76ccae9134780a3e72cb1162ec82f452e521fa64581418": {
"Name": "redis_container",
"EndpointID": "089ce4c9e7283361c14c126612cdafd416d9ba55feb265ec33d365bc12a26a53",
"MacAddress": "ca:d8:88:35:12:4b",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"e9f11e99df4f75c6fd805ccd4289740faae0a03c8d12a514cfa6d30eb90c633a": {
"Name": "postgres_container",
"EndpointID": "e0d9cb031ee55ea11109a44887bb5e036bb810a2f06c9a3ddab2bea25e858a3c",
"MacAddress": "e6:87:c3:72:53:6c",
"IPv4Address": "172.18.0.4/16",
"IPv6Address": ""
}
},
"Status": {
"IPAM": {
"Subnets": {
"172.18.0.0/16": {
"IPsInUse": 9,
"DynamicIPsAvailable": 65527
}
}
}
}
}
]
C:\Users\CodewithDev>
Additionally, I have included a Postgres database, Redis for caching, and Celery and Celery Beat for the task queue. It is connected internally to the bridge network, which is isolated from the frontend network. Since we have created a custom network, the external container can now communicate with the blog network.

In this way, you can Manage Multiple Docker Compose files in the same Network, and this network will stay connected unless you delete the container, unlike the terminal. Now, let’s understand the default and custom bridge network. Since our blog network was used as a bridge network internally.
Default Network vs Custom Bridge Network
When you run multiple services in the docker-compose.yml file, it will automatically create a default network, which means it creates a bridge network so that each container can communicate with each other, even if you don’t mention the network in your services and define the network at the bottom.
Which you will see in the Windows PowerShell, open Windows PowerShell, and run this command,
docker network ls
Before running this command, make sure your Docker Desktop is up and running. Here you will see it’s creating a default network even if you don’t mention the network in your docker-compose.yml file.
Disadvantages of Default Network
The first disadvantage of using the default network is that your container can’t communicate with another container by name, but only with an IP address.
You can’t isolate any Docker container, which is inside the docker-compose.yml, as it will by default use the same default network, which was created when you ran the build and up commands.
Not scalable, since it will create a default network without proper naming, and it will be hard to identify when your application will scale up.
Benefits of using Custom Bridge Network
You can isolate Docker containers by creating a custom bridge
network, which means just take an example, your Redis running on the
shared infrastructure network, and your Django rest framework
running on the e-commerce network, which means both of the services
are isolated.
When you use a custom bridge network, the container can communicate
through both the container name and IP address. This is the benefit
of using a custom bridge network.
More scalable since you can easily identify which network is being
used among these containers.
A few days ago, I was working on the Same Architecture, and I successfully communicated with the different network containers. We use service names to fetch blog posts or products.
And that’s pretty much it for this article. If you learn something new, let me know your thoughts. Maybe I will see you in the next one. Peace out!