Docker Networking – How Containers Talk to Each Other

Every container needs to communicate — with users, with databases, with other services. Docker has a built-in networking system that gives containers their own IP addresses, lets them talk to each other, and controls what is accessible from outside. This topic explains Docker networking through diagrams and practical examples.

The Default Network Setup

When you install Docker, it automatically creates three networks:

docker network ls

NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
b2c3d4e5f6g7   host      host      local
c3d4e5f6g7h8   none      null      local

The Bridge Network — The Default

Every container you start without specifying a network joins the default bridge network automatically. Docker creates a virtual network switch inside your machine and assigns each container an IP address on the 172.17.0.0/16 range.

Default Bridge Network:

Your Machine (host)
┌──────────────────────────────────────────────────┐
│                                                  │
│  Docker Bridge Network: 172.17.0.0/16            │
│  ┌─────────────────────────────────────────────┐ │
│  │                                             │ │
│  │  Container A          Container B           │ │
│  │  nginx                mysql                 │ │
│  │  IP: 172.17.0.2       IP: 172.17.0.3        │ │
│  │                                             │ │
│  │  Container A can reach B via 172.17.0.3     │ │
│  └─────────────────────────────────────────────┘ │
│                                                  │
│  Your machine IP: 172.17.0.1 (gateway)           │
└──────────────────────────────────────────────────┘

The limitation of the default bridge: containers can reach each other by IP address but NOT by name. If Container A wants to reach MySQL, it must know MySQL's IP address (172.17.0.3), which can change every time you restart the container.

Custom Bridge Networks — The Right Way

Create your own bridge network to get automatic DNS resolution. Containers on the same custom network can reach each other by container name — no IP addresses needed.

Create a custom network:
docker network create my-app-network

Run containers on this network:
docker run -d --name web --network my-app-network nginx
docker run -d --name db  --network my-app-network mysql:8.0

Now "web" can reach "db" by name:
Inside the web container: ping db → works!
Inside the web container: mysql -h db → works!
Custom Bridge Network with DNS:

┌─────────────────────────────────────────────────┐
│  my-app-network                                 │
│                                                 │
│  Container "web"        Container "db"          │
│  nginx                  mysql                   │
│  10.0.0.2               10.0.0.3                │
│                                                 │
│  web can use: http://db:3306/                   │
│  No need to know IP addresses                   │
│  Docker's built-in DNS resolves "db" → 10.0.0.3 │
└─────────────────────────────────────────────────┘

Port Mapping — Connecting Containers to the Outside World

By default, containers are isolated. External traffic cannot reach them. Port mapping creates a tunnel from your host machine into the container.

docker run -d -p 8080:80 nginx

Port Mapping:
  Internet/Browser                Your Machine          Container
       ↓                         ┌──────────┐          ┌────────┐
  GET http://                    │          │          │        │
  yourserver.com:8080 ─────────→ │  :8080   │────────→ │  :80   │
                                 │          │          │ nginx  │
                                 └──────────┘          └────────┘

Format: -p HOST_PORT:CONTAINER_PORT

Multiple port mappings on one container:

docker run -d -p 8080:80 -p 443:443 nginx

Bind to a specific host interface (limit who can reach the port):

docker run -d -p 127.0.0.1:8080:80 nginx
             ↑
             Only localhost can reach this — not external traffic

Host Network Mode

In host network mode, the container shares your machine's network directly. There is no isolation — the container uses your machine's IP and ports as if it were a regular process.

docker run -d --network host nginx

nginx now listens on your machine's port 80 directly. No port mapping needed. This is faster but less isolated — only use it when performance is critical.

Network Commands Reference

List networks:          docker network ls
Create network:         docker network create my-net
Inspect network:        docker network inspect my-net
Connect container:      docker network connect my-net web
Disconnect container:   docker network disconnect my-net web
Remove network:         docker network rm my-net
Remove unused:          docker network prune

Container-to-Container Communication Example

Goal: Python web app talks to Redis cache

docker network create app-net

docker run -d \
  --name redis \
  --network app-net \
  redis:7

docker run -d \
  --name webapp \
  --network app-net \
  -p 5000:5000 \
  -e REDIS_HOST=redis \
  my-flask-app

Inside webapp: redis.connect("redis", 6379) → works!
"redis" resolves to the Redis container's IP automatically

Leave a Comment