All Articles

What is Docker Network? Explained Simply for Beginners (2026)

How do Docker containers talk to each other and to the outside world? Here's what Docker networking is, the difference between bridge, host, and overlay networks, and practical examples you'll use every day.

DevOpsBoysApr 26, 20265 min read
Share:Tweet

You have two Docker containers — a web app and a database. How does the web app connect to the database? How does the outside world reach your web app? That's Docker networking.

Here's how it works.


The Problem Docker Networking Solves

Each container is isolated. By default, a container can't talk to another container, and nothing outside can reach it. Docker networking creates controlled channels for communication.

Without networking:
[ Container A ] ←X→ [ Container B ]   (can't communicate)

With Docker bridge network:
[ Container A ] ←──→ [ Docker Bridge ] ←──→ [ Container B ]

The Four Network Drivers

Docker has four built-in network types:

1. Bridge (Default)

The most common. Docker creates a virtual switch. Containers on the same bridge network can talk to each other by container name.

bash
# Create a custom bridge network
docker network create myapp-network
 
# Run containers on it
docker run -d --name postgres --network myapp-network postgres:16
docker run -d --name webapp --network myapp-network myapp:latest
 
# webapp can now reach postgres at hostname "postgres"
# Inside webapp container:
# psql -h postgres -U user mydb   ← works!

Default bridge vs custom bridge:

  • Default bridge (docker0): containers can only reach each other by IP address
  • Custom bridge: containers reach each other by container name (automatic DNS)

Always use custom bridge networks — name-based discovery is much easier.

2. Host

The container shares the host machine's network directly. No isolation.

bash
docker run -d --network host nginx
# Nginx now listens on the HOST's port 80 directly
# No -p port mapping needed

When to use: When you need maximum network performance and don't need isolation. Common for monitoring agents (like Node Exporter) that need to see host network stats.

Never use for web apps — it bypasses container isolation.

3. None

No network at all. Completely isolated.

bash
docker run --network none ubuntu
# This container has no network interfaces
# Use for security-sensitive batch jobs

4. Overlay

Spans multiple Docker hosts (Docker Swarm). Containers on different machines can communicate as if they're on the same network.

bash
# Docker Swarm only
docker network create --driver overlay myapp-overlay

How Container-to-Container Communication Works

docker network create myapp-net

docker run -d \
  --name db \
  --network myapp-net \
  -e POSTGRES_PASSWORD=secret \
  postgres:16

docker run -d \
  --name web \
  --network myapp-net \
  -e DATABASE_URL="postgresql://postgres:secret@db:5432/mydb" \
  -p 8080:3000 \
  myapp:latest

web reaches db at hostname db — Docker's internal DNS resolves container names to their IP addresses automatically.

bash
# Verify from inside the web container
docker exec web ping db
docker exec web nc -zv db 5432

Port Mapping — How the Outside World Reaches Containers

By default, containers are invisible to the outside world. Port mapping (-p) creates a tunnel:

bash
docker run -d -p 8080:3000 myapp:latest
#               ↑     ↑
#         host port  container port
 
# Now: requests to localhost:8080 → container port 3000

Multiple ports:

bash
docker run -d \
  -p 80:80 \
  -p 443:443 \
  nginx:latest

Bind to specific interface (more secure):

bash
# Only accessible from localhost, not other machines on the network
docker run -d -p 127.0.0.1:5432:5432 postgres:16

Docker Compose Networking

Docker Compose automatically creates a bridge network for your entire stack. All services can reach each other by service name.

yaml
# docker-compose.yml
services:
  web:
    image: myapp:latest
    ports:
      - "8080:3000"
    depends_on:
      - db
      - redis
 
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    # No ports exposed — only accessible from within the stack
 
  redis:
    image: redis:7-alpine
    # No ports exposed
python
# In your app code:
import psycopg2
conn = psycopg2.connect(host="db", port=5432, ...)
# "db" resolves to the postgres container automatically

Important: The database ports are NOT exposed to your host machine. Only web:8080 is accessible from your browser. db and redis are only reachable from within the Docker network — which is exactly what you want for security.

To expose a service for debugging:

yaml
db:
  image: postgres:16
  ports:
    - "5432:5432"  # Now accessible from host for debugging

Multiple Networks for Isolation

You can put containers on multiple networks to control who can talk to whom:

yaml
services:
  nginx:
    image: nginx:latest
    networks:
      - frontend
    ports:
      - "80:80"
 
  webapp:
    image: myapp:latest
    networks:
      - frontend   # can talk to nginx
      - backend    # can talk to db
 
  db:
    image: postgres:16
    networks:
      - backend    # ONLY accessible from webapp, not nginx
 
networks:
  frontend:
  backend:

nginx → can reach webapp
webapp → can reach db
nginx → cannot reach db ❌ (different network — good for security)


Common Network Commands

bash
# List all networks
docker network ls
 
# Inspect a network (see connected containers + IPs)
docker network inspect myapp-network
 
# Create a network
docker network create myapp-network
 
# Connect a running container to a network
docker network connect myapp-network mycontainer
 
# Disconnect a container from a network
docker network disconnect myapp-network mycontainer
 
# Remove a network (all containers must be disconnected first)
docker network rm myapp-network
 
# Remove all unused networks
docker network prune

DNS Resolution Inside Docker

Docker runs a built-in DNS server at 127.0.0.11. Every container on a custom network uses it.

bash
# Check DNS resolution inside a container
docker exec webapp nslookup db
# Server: 127.0.0.11
# Address: 127.0.0.11#53
# Name: db
# Address: 172.18.0.3

This is why you can use service names instead of IP addresses — IPs change when containers restart, but names always resolve correctly.


Common Networking Problems

Container can't reach another container:

bash
# Are they on the same network?
docker inspect container1 | grep NetworkMode
docker inspect container2 | grep NetworkMode
 
# Check if container names resolve
docker exec container1 ping container2

Port not accessible from host:

bash
# Check port mapping
docker ps
# Look for: 0.0.0.0:8080->3000/tcp
 
# Check if something else is using the port
netstat -tulnp | grep 8080

Works in Docker Compose but not standalone:

bash
# Compose creates a network automatically — standalone doesn't
# Create network first, then use --network flag
docker network create myapp-net
docker run --network myapp-net ...

Docker networking is one of those topics that seems complicated but follows a consistent pattern: containers on the same custom network can reach each other by name, the outside world reaches containers through port mapping, and multiple networks give you security isolation.

For hands-on practice, Docker & Kubernetes Complete Guide covers Docker networking with real multi-container project examples.

Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments