Docker Networking - Container Communication

Status: Active
Last Updated: 2026-01-30
Category: Containers - Networking
Prerequisites: docker-basics, docker-concepts, kb/basics/linux-fundamentals
Time: 3-4 hours
Tags: docker, networking, bridge, host, overlay, macvlan, dns

Summary

Master Docker networking to connect containers, expose services, and build multi-tier applications. Learn network drivers, DNS resolution, port mapping, network isolation, and troubleshooting container connectivity.

๐ŸŽฏ What You'll Learn

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

๐ŸŒ Docker Network Basics

Default Behavior:

# Run container without network flags
docker run -d --name web nginx

# Container gets:
# - Private IP address
# - Connected to default bridge network
# - Can reach internet
# - NOT accessible from host (unless ports mapped)

๐Ÿ”Œ Network Drivers

Docker provides several network drivers:

Quick Comparison

Driver Use Case Container-to-Container External Access Performance
bridge Single host By IP only (default) Port mapping Good
user-defined bridge Single host apps By name (DNS!) Port mapping Good
host Performance N/A Direct Best
overlay Swarm/multi-host By name Port mapping Good
macvlan Legacy apps Like physical network Direct Good
none Maximum isolation None None N/A

๐ŸŒ‰ Bridge Network (Default)

Bridge Network: Default network for containers.

Characteristics:

Default Bridge Network

# Run containers on default bridge
docker run -d --name web1 nginx
docker run -d --name web2 nginx

# Get IPs
docker inspect web1 | grep IPAddress
# "IPAddress": "172.17.0.2"

docker inspect web2 | grep IPAddress
# "IPAddress": "172.17.0.3"

# Containers can ping by IP
docker exec web1 ping 172.17.0.3
# Works!

# But NOT by name (no DNS)
docker exec web1 ping web2
# Fails! โŒ

User-Defined Bridge (Recommended)

User-Defined Bridge: Custom bridge network with DNS!

# Create custom bridge network
docker network create my-network

# Run containers on custom network
docker run -d --name web --network my-network nginx
docker run -d --name db --network my-network postgres:15

# Containers can reach each other BY NAME! ๐ŸŽ‰
docker exec web ping db
# Works! DNS resolves db โ†’ IP

docker exec db ping web
# Works! DNS resolves web โ†’ IP

Why Custom Bridge?:


๐Ÿ—๏ธ Network Management

Create Network

# Basic custom network
docker network create my-app-network

# With subnet
docker network create \
  --subnet=192.168.100.0/24 \
  --gateway=192.168.100.1 \
  my-network

# With IP range
docker network create \
  --subnet=172.20.0.0/16 \
  --ip-range=172.20.1.0/24 \
  my-network

List Networks

# List all networks
docker network ls

# Output:
NETWORK ID     NAME              DRIVER    SCOPE
3f7a8c9b2e1d   bridge            bridge    local
5a8d3e2f1c4b   host              host      local
7d9e4f3a2b1c   none              null      local
abc123def456   my-app-network    bridge    local

Inspect Network

# Get network details
docker network inspect my-app-network

# See connected containers
docker network inspect my-app-network | grep -A 10 Containers

# Formatted output
docker network inspect --format='{{range .Containers}}{{.Name}} {{end}}' my-app-network

Connect Container to Network

# Connect existing container to network
docker network connect my-network my-container

# Container now on multiple networks!

# Connect with custom IP
docker network connect --ip 192.168.100.10 my-network my-container

# Connect with alias (additional DNS name)
docker network connect --alias db-master my-network my-postgres

Disconnect Container

# Disconnect container from network
docker network disconnect my-network my-container

Remove Network

# Remove network (no containers connected)
docker network rm my-network

# Remove all unused networks
docker network prune

๐Ÿ”Œ Port Mapping

Port Mapping: Expose container ports to host.

Basic Port Mapping

# Map host port 8080 โ†’ container port 80
docker run -d -p 8080:80 --name web nginx

# Access from host
curl http://localhost:8080

Syntax:

-p HOST_PORT:CONTAINER_PORT

Advanced Port Mapping

# Bind to specific host IP
docker run -d -p 127.0.0.1:8080:80 nginx
# Only accessible from localhost

# Map to random host port
docker run -d -p 80 nginx
# Docker assigns random high port (e.g., 32768)

# Find assigned port
docker port my-container
# 80/tcp -> 0.0.0.0:32768

# Multiple port mappings
docker run -d \
  -p 8080:80 \
  -p 8443:443 \
  nginx

# UDP port
docker run -d -p 53:53/udp dns-server

# Multiple interfaces
docker run -d \
  -p 192.168.1.10:8080:80 \
  -p 10.0.0.10:8080:80 \
  nginx

๐ŸŽฏ Real-World Network Examples

Example 1: Web App with Database

# Create network
docker network create app-network

# Run database (no ports exposed to host!)
docker run -d \
  --name postgres \
  --network app-network \
  -e POSTGRES_PASSWORD=secret \
  postgres:15

# Run web app
docker run -d \
  --name webapp \
  --network app-network \
  -p 8080:8080 \
  -e DATABASE_URL=postgresql://postgres:secret@postgres:5432/app \
  my-webapp:latest

# Web app connects to postgres by name
# Only port 8080 exposed to outside

Example 2: Microservices Architecture

# Create network
docker network create microservices

# Frontend
docker run -d \
  --name frontend \
  --network microservices \
  -p 80:80 \
  frontend-app:latest

# Auth service (internal only)
docker run -d \
  --name auth \
  --network microservices \
  -e JWT_SECRET=secret123 \
  auth-service:latest

# User service (internal only)
docker run -d \
  --name users \
  --network microservices \
  -e DATABASE_URL=postgresql://db:5432/users \
  user-service:latest

# Database (internal only)
docker run -d \
  --name db \
  --network microservices \
  -e POSTGRES_PASSWORD=secret \
  postgres:15

# All services communicate by name
# Only frontend accessible from outside

Example 3: Development with Multiple Networks

# Frontend network
docker network create frontend-net

# Backend network
docker network create backend-net

# Database (backend only)
docker run -d \
  --name db \
  --network backend-net \
  postgres:15

# API (both networks)
docker run -d \
  --name api \
  --network backend-net \
  my-api:latest

docker network connect frontend-net api

# Web (frontend only)
docker run -d \
  --name web \
  --network frontend-net \
  -p 8080:80 \
  my-web:latest

# Result:
# - web can reach api (both on frontend-net)
# - api can reach db (both on backend-net)
# - web CANNOT reach db (isolated!)

๐Ÿ  Host Network Driver

Host Network: Container uses host's network directly.

Characteristics:

# Run with host network
docker run -d --network host nginx

# Container binds to host's ports directly
# Access via host's IP:
curl http://<host-ip>:80

Use Cases:

Limitations:


๐Ÿšซ None Network Driver

None Network: No networking.

# Run with no network
docker run -d --network none alpine sleep infinity

# Container has no network interfaces (except loopback)
docker exec my-container ip addr
# Only lo (127.0.0.1)

Use Cases:


๐Ÿ” DNS and Service Discovery

Automatic DNS

User-defined bridges provide automatic DNS:

# Create network
docker network create app-net

# Run services
docker run -d --name web --network app-net nginx
docker run -d --name api --network app-net my-api:latest
docker run -d --name db --network app-net postgres:15

# Services resolve each other by name
docker exec web ping api     # Works!
docker exec api ping db      # Works!
docker exec db ping web      # Works!

DNS Aliases

Add multiple DNS names:

# Run with alias
docker run -d \
  --name postgres-primary \
  --network app-net \
  --network-alias db \
  --network-alias database \
  postgres:15

# Can reach by any name:
docker exec app ping postgres-primary  # Works
docker exec app ping db                # Works
docker exec app ping database          # Works

Custom DNS Servers

# Use custom DNS server
docker run -d \
  --dns 8.8.8.8 \
  --dns 1.1.1.1 \
  nginx

# Add DNS search domains
docker run -d \
  --dns-search example.com \
  --dns-search internal.example.com \
  nginx

๐Ÿ”ฌ Network Troubleshooting

Check Container Network

# Get container IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container

# Get all network info
docker inspect my-container | grep -A 20 NetworkSettings

# Check which networks container is on
docker inspect -f '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' my-container

Test Connectivity

# Ping another container
docker exec my-container ping other-container

# Check DNS resolution
docker exec my-container nslookup other-container

# Test HTTP connectivity
docker exec my-container curl http://other-container:8080

# Check open ports
docker exec my-container netstat -tulpn

Debug Network Issues

# Run temporary debug container
docker run --rm -it --network my-network nicolaka/netshoot

# Inside debug container:
# - ping other containers
# - nslookup container-name
# - curl http://container-name
# - tcpdump
# - traceroute

Common Issues

Issue 1: Containers Can't Communicate

# Check if on same network
docker network inspect my-network

# Solution: Connect to same network
docker network connect my-network container1
docker network connect my-network container2

Issue 2: DNS Not Working

# Default bridge doesn't have DNS
# Solution: Use custom network
docker network create my-net
docker run --network my-net ...

Issue 3: Port Already in Use

# Check what's using port
sudo netstat -tulpn | grep :8080

# Solution: Use different host port
docker run -p 8081:80 nginx

๐Ÿท๏ธ Network Labels and Metadata

# Create network with labels
docker network create \
  --label project=myapp \
  --label environment=production \
  myapp-prod-network

# Filter networks by label
docker network ls --filter label=project=myapp

# Inspect labels
docker network inspect myapp-prod-network | grep -A 5 Labels

โš™๏ธ Advanced Network Options

Internal Networks

Internal Network: No external connectivity.

# Create internal network (no internet access)
docker network create --internal secure-network

# Containers can reach each other but not internet
docker run -d --name db --network secure-network postgres:15

docker exec db ping google.com
# Fails! No external access

IPv6 Networks

# Enable IPv6
docker network create \
  --ipv6 \
  --subnet=2001:db8:1::/64 \
  my-ipv6-network

# Run container with IPv6
docker run -d --network my-ipv6-network nginx

Network Scopes

# Local scope (single host)
docker network create --scope local my-local-net

# Swarm scope (multi-host) - requires Swarm mode
docker network create --scope swarm --driver overlay my-overlay-net

๐Ÿ’ก Best Practices

1. Use Custom Networks

# Good: Custom network with DNS
docker network create my-app
docker run --network my-app --name web nginx
docker run --network my-app --name db postgres

# Bad: Default bridge (no DNS)
docker run --name web nginx
docker run --name db postgres

2. Network Isolation

# Separate networks for different tiers
docker network create frontend
docker network create backend

# API server on both (gateway)
docker run --name api --network backend my-api
docker network connect frontend api

# Web on frontend only
docker run --network frontend --name web my-web

# DB on backend only (isolated!)
docker run --network backend --name db postgres

3. Don't Expose Unnecessary Ports

# Good: Only expose what's needed
docker run -d \
  --name db \
  --network app-net \
  postgres:15
# No -p flag! Only accessible within network

# Bad: Exposing database to world
docker run -d \
  -p 5432:5432 \
  postgres:15
# Now anyone can try to connect! ๐Ÿ˜ฑ

4. Use Network Aliases

# Primary database
docker run -d \
  --name postgres-01 \
  --network app-net \
  --network-alias db \
  --network-alias primary \
  postgres:15

# App connects to "db" or "primary"
# Easy to swap instances

๐Ÿ”— What's Next?

Now that you understand Docker networking:

Multi-Container Apps:

Advanced Networking:

Container Orchestration:


๐Ÿ“š Resources

Official Docs:

Tools:


๐Ÿ“ Change Log

2026-01-30


Next Article: docker-compose-intro - Simplify multi-container apps!

Choose Theme

Your selection is saved locally.

Neural Cacophony
Aperture v2
Flux v1
Mosaic Chaos
Nexus v1
Nexus Zest
Prism v2
Synapse