Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 60

"Custom Docker Bridge Networks for Hostname Communication"

Recommended resources

Welcome back! In our last lesson, we mastered how to write a production-ready Dockerfile to build a small, fast, and secure image for a single service. This is a crucial first step. However, microservice architectures are, by definition, composed of multiple services that need to work together.

This brings us to a fundamental question: how do these isolated containers communicate with each other? In this lesson, we will answer that by exploring Docker networking. You will learn how to create a custom Docker bridge network, which enables your containerized services to discover and communicate with each other simply by using their names, a foundational requirement for building any multi-service application.

1. The Default Bridge Network and Its Limitations

When you run a container without specifying a network, Docker automatically connects it to a default network named bridge. While this provides basic connectivity, it has a significant drawback for microservices.

To understand this limitation, let's watch a short segment from the "Docker Networking Tutorial" video by Anton Putra.

Docker Networking Tutorial (Bridge - None - Host - IPvlan - Macvlan - Overlay)

This video introduces the default bridge network and its primary limitation for inter-container communication.

Watch the section that explains the default bridge network. Focus on the key takeaway: containers on this network can communicate, but they must use each other's IP addresses. The video highlights that this approach is not recommended, especially for production.

As the video explains, containers on the default bridge network can only find each other using their internal IP addresses. This is problematic for a microservices architecture for a few key reasons:

  • IPs are Ephemeral: A container's IP address can change every time it is stopped and restarted. Hardcoding IP addresses in your application configuration would create an incredibly brittle system.
  • Manual Configuration: Relying on IPs forces you to manually discover and configure the addresses of your services, which is impractical and doesn't scale.

Imagine your Order Service needs to call your Payment Service. If you have to look up the Payment Service's IP address every time it deploys, your system is fragile. What we need is a stable way for services to find each other, much like you use a domain name (e.g., google.com) instead of memorizing Google's server IP addresses. This is where user-defined networks come in.


2. The Power of User-Defined Bridge Networks

To solve the limitations of the default network, Docker allows you to create your own user-defined bridge networks. These custom networks are the recommended approach for production applications and provide several key advantages.

Differences between user-defined bridges and the default bridge

The official Docker documentation provides the best summary of why you should always use custom networks.

Read the section titled "Differences between user-defined bridges and the default bridge". Pay close attention to the first point: "User-defined bridges provide automatic DNS resolution between containers." This is the most critical feature for our purposes.

The ability for containers to resolve each other by name is a game-changer. When you place multiple containers on the same custom network, Docker provides a built-in DNS server. This server maps the container's name to its internal IP address automatically.

If you have a container named api and another named db on the same custom network, the api container can simply connect to the hostname db. Docker's internal DNS will resolve db to the correct IP address, no matter how many times the db container restarts.

Docker Bridge Network Comparison
This diagram shows two isolated bridge networks. Containers `c1` and `c2` are on the default 'bridge' network, while `c3` and `c4` are on a 'custom bridge' network. They can communicate within their respective networks, but not across them, providing essential isolation.

3. Creating and Using a Custom Bridge Network

Let's see this in action. The process involves two simple steps: creating the network and then launching containers into it.

Step 1: Create the Network

You create a custom bridge network with the docker network create command.

docker network create my-app-net

This command creates a new, isolated network named my-app-net. You can verify it was created by running docker network ls.

Step 2: Run Containers on the Network

To attach a container to this network, you use the --network flag with the docker run command.

The following video provides a clear, practical demonstration of creating a network, launching two containers into it, and verifying they can communicate by name.

Docker Networking Tutorial (Bridge - None - Host - IPvlan - Macvlan - Overlay)

This part of the "Docker Networking Tutorial" shows a complete end-to-end example.

Watch the demonstration on creating and using a custom network. Observe how the docker network create command is used, how containers are launched with the --network flag, and most importantly, how curl successfully resolves the other container's name inside the network.


4. Hands-on Exercise: Service-to-Service Communication

Now it's your turn to build this yourself. We'll simulate a basic microservice setup: a web service and a database service.

  1. Create the network:
    First, create a network for our application. Let's call it ecom-net.

    docker network create ecom-net
    
  2. Run the "database" service:
    We'll use a standard postgres image to simulate our database. We'll name this container db.

    
    
    
    # We use -d to run it in the background
    # We set a password, which is required by the postgres image
    docker run -d \
      --name db \
      --network ecom-net \
      -e POSTGRES_PASSWORD=mysecretpassword \
      postgres:15-alpine
    

    This container is now running on the ecom-net network and is reachable at the hostname db.

  3. Run a "client" service and test communication:
    Now, let's run a temporary container to simulate another service (e.g., an api service) trying to connect to the database. We will use the alpine image, which is very small, and attach a shell to it.

    
    
    
    # --rm automatically removes the container when we exit
    docker run -it --rm \
      --network ecom-net \
      alpine:latest sh
    
  4. Verify DNS resolution from inside the client container:
    Once you are inside the alpine container's shell (you'll see a # prompt), you first need to install a tool to test network connectivity, like ping. Alpine's package manager is apk.

    
    
    
    # Inside the alpine container's shell
    apk add --no-cache iputils
    

    Now, try to ping the database container using its hostname:

    
    
    
    # Inside the alpine container's shell
    ping -c 3 db
    

    You should see a successful response, similar to this:

    PING db (172.19.0.2): 56 data bytes
    64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.138 ms
    64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.103 ms
    64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.100 ms
    

    This proves that your client container was able to resolve the hostname db to the correct IP address and establish communication. You have successfully enabled service discovery! Type exit to leave the alpine container.

  5. Clean up:
    Finally, stop and remove the db container and the network.

    docker stop db
    docker rm db
    docker network rm ecom-net
    

Conclusion

You have now bridged a critical gap between running a single container and orchestrating a multi-service application. Manually managing individual containers and networks with these commands is insightful, but it can quickly become cumbersome.

Key Takeaways:

  • The default bridge network is not suitable for microservices because it relies on unstable IP addresses for communication.
  • User-defined bridge networks provide crucial features for microservices:
    • Network Isolation: Services are sandboxed within their own private network.
    • Automatic DNS Resolution: Containers can reliably discover and communicate with each other using their container names as hostnames.
  • The core commands are docker network create to build the network and docker run --network <name> to connect a container to it.

Preview of the Next Lesson

We've seen how to manually create a network and connect containers. In our next lesson, we will learn how to use Docker Compose. You'll discover how to define and run a complete multi-service application—including all its services, networks, and volumes—from a single, declarative docker-compose.yml file. This will automate everything we just did by hand and is the standard way to manage local development environments for microservices.