7. Docker Networking Explained | The Complete Docker Handbook.

6 mins read
0 Like
23 Views

Welcome to Article 7 of The Complete Docker Handbook.

In Article 6, we solved the data persistence problem using Volumes. Now we face another challenge: Communication.

By default, Docker containers are isolated. They run in their own little worlds.

  • How does your frontend container talk to your backend container?
  • How does your backend container connect to the database?
  • How do you access your running container from your web browser?

If you try to ping one container from another out of the box, it might fail. If you try to access a port, it might be blocked.

In this article, we will demystify Docker Networking. You will learn how to connect containers, expose ports to the outside world, and use Docker's built-in DNS for seamless service discovery.


1. The Default Network Behavior

When you install Docker, it creates several default networks. You can see them by running:

Bash
docker network ls

Output:

Plain Text
1NETWORK ID     NAME      DRIVER    SCOPE
2a8f2c3d4e5f6   bridge    bridge    local
3b9g3d4e5f6g7   host      host      local
4c0h4e5f6g7h8   none      null      local
  • bridge (Default): When you run a container without specifying a network, it connects to this default bridge network. Containers on this network can access the outside world (internet), but they cannot resolve each other by name. You would need to use IP addresses, which change every time you restart.
  • host: The container shares the host's networking namespace. No isolation. (Linux only).
  • none: No networking at all.

> ⚠️ Critical Tip: For multi-container applications, do not use the default bridge network. Instead, create a User-Defined Bridge Network. This enables automatic DNS resolution.


2. Port Mapping (Exposing Services)

Containers have their own internal IP addresses (e.g., 172.17.0.2). Your computer cannot see these IPs directly. To access a web server running inside a container from your browser, you need Port Mapping.

The -p Flag

Syntax: -p :

Bash
docker run -p 8080:80 nginx
  • 8080 (Host Port): The port on your laptop/server. You visit localhost:8080.
  • 80 (Container Port): The port the application is actually listening on inside the container.
  • What happens: Docker creates a firewall rule that forwards traffic from your computer's port 8080 to the container's port 80.

Common Port Mapping Scenarios

  • Web Server: -p 80:80 (Standard HTTP)
  • Dev Server: -p 3000:3000 (Node.js React app)
  • Database: -p 5432:5432 (PostgreSQL)
    • Security Note: Be careful mapping database ports to the host. Anyone who can access your host IP can try to connect to your database. In production, databases should usually not have port mapping; they should only be accessible by other containers on the same network.

3. Container-to-Container Communication

This is the most important concept for microservices. How does the API container find the Database container?

The Problem with IP Addresses

If you start a database container, it might get IP 172.18.0.2. If you restart it, it might get 172.18.0.3. Hardcoding IPs in your application code is a bad idea.

The Solution: User-Defined Networks & DNS

When you create a User-Defined Bridge Network, Docker provides automatic DNS resolution. Containers can ping each other using their container names.

Practical Lab: Connecting App to DB

Let's create a network and run two containers that can talk to each other.

Step 1: Create a Network

Bash
docker network create my-app-network

Step 2: Run a Database Container We'll name it db and attach it to the network.

Bash
1docker run -d \
2  --name db \
3  --network my-app-network \
4  -e POSTGRES_PASSWORD=secret \
5  postgres

Step 3: Run a Web Container to Test Connection We'll run a temporary container with ping installed to test connectivity.

Bash
1docker run -it --rm \
2  --network my-app-network \
3  alpine ping db

Output:

Plain Text
1PING db (172.18.0.2): 56 data bytes
264 bytes from 172.18.0.2: seq=0 ttl=64 time=0.15 ms
364 bytes from 172.18.0.2: seq=1 ttl=64 time=0.20 ms
4...

Success! Notice we pinged db (the container name), not an IP address. Docker's internal DNS resolved db to the correct IP. Even if the database container restarts and gets a new IP, the name db will always resolve correctly.


4. Network Drivers Deep Dive

While bridge is the most common, you should know the others.

Driver Description Use Case
bridge Private network on the host. Containers communicate via IP/DNS. Default for single-host apps.
host Container uses the host's network directly. No port mapping needed. High performance needs (e.g., monitoring agents). Less secure.
none No network interface. Isolated security tasks.
overlay Connects multiple Docker daemons (swarm). Docker Swarm / Multi-host clusters.
macvlan Assigns a MAC address to the container (appears as physical device). Legacy apps needing direct physical network connection.

5. Inspecting and Debugging Networks

When things go wrong (e.g., "Connection Refused"), use these commands to debug.

1. Inspect the Network See which containers are connected and their subnet.

Bash
docker network inspect my-app-network

Look for the Containers section to see IP addresses assigned.

2. Check Container IP

Bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'

3. Test Connectivity from Inside If your app can't connect to the DB, exec into the app container and try to ping the DB.

Bash
docker exec -it  ping db

6. Security Best Practices

  1. Isolate Tiers: Create separate networks for different tiers.
    • frontend-net: Connects Web + Load Balancer.
    • backend-net: Connects Web + API + Database.
    • Result: The Load Balancer cannot directly access the Database.
  2. Don't Expose DB Ports: As mentioned earlier, avoid -p 5432:5432 for databases in production. Only connect them via internal networks.
  3. Use Internal Flag: You can create a network with --internal flag. This blocks access to the external internet entirely. Great for databases that don't need to download updates.
    Plain Text
    1bash
    2docker network create --internal db-network

Summary Checklist

By the end of this article, you should be able to:

  • Explain the difference between Host and Container ports.
  • Create a user-defined bridge network.
  • Connect containers using DNS names instead of IPs.
  • Inspect network details using docker network inspect.
  • Understand security implications of port mapping.

What's Next?

You now know how to manage containers, networks, and volumes manually using the CLI. But imagine running a stack with 5 containers, 3 networks, and 2 volumes. Typing all those docker run commands every time would be a nightmare.

Enter Docker Compose.

In Article 8, we will introduce the docker-compose.yml file. You will learn how to define your entire infrastructure (networks, volumes, services) in a single text file and launch it with one command.

Link: Read Article 8: Introduction to Docker Compose


Challenge: Create a custom network called web-net. Run an nginx container named web on it. Run an alpine container on the same network and curl the web container using its name (curl web).

Next Up: Introduction to Docker Compose

Share:

Comments

0
Join the conversation

Sign in to share your thoughts and connect with other readers

No comments yet

Be the first to share your thoughts!