Learning Guides
Menu

Container Networking

9 min readDocker for Developers

Container Networking

Networking enables containers to communicate with each other and the outside world. This chapter covers Docker's networking model, network drivers, and how to connect containers effectively.

Docker Networking Basics

By default, Docker creates an isolated network environment for each container. Containers can:

  • Communicate with the host machine
  • Access the internet (outbound)
  • Be connected to other containers through networks
BASH
# View existing networks
docker network ls
 
# Default networks
NETWORK ID     NAME      DRIVER    SCOPE
abc123         bridge    bridge    local
def456         host      host      local
ghi789         none      null      local

Network Drivers

Docker supports several network drivers for different use cases:

Bridge Network (Default)

The default network driver. Containers on the same bridge network can communicate via IP addresses.

BASH
# Create a bridge network
docker network create mynetwork
 
# Run containers on the network
docker run -d --name web --network mynetwork nginx
docker run -d --name api --network mynetwork node:20-alpine
 
# Containers can reach each other by name
docker exec web ping api

Bridge Network Diagram

PLAINTEXT
┌─────────────────────────────────────────────────────────┐
│                      Host Machine                        │
│  ┌─────────────────────────────────────────────────┐    │
│  │              Docker Bridge Network               │    │
│  │                  (172.17.0.0/16)                │    │
│  │                                                  │    │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐      │    │
│  │  │   web    │  │   api    │  │   db     │      │    │
│  │  │172.17.0.2│  │172.17.0.3│  │172.17.0.4│      │    │
│  │  └──────────┘  └──────────┘  └──────────┘      │    │
│  │                                                  │    │
│  └─────────────────────────────────────────────────┘    │
│                         │                                │
│                    NAT/Port Mapping                      │
│                         │                                │
│                    ┌────┴────┐                          │
│                    │ eth0    │                          │
└────────────────────┴─────────┴───────────────────────────┘

                      Internet

Host Network

Containers share the host's network stack directly. No network isolation.

BASH
# Run with host network
docker run -d --network host nginx
 
# Container ports are directly on host
# No need for -p port mapping
curl localhost:80

Warning

Host networking removes network isolation. The container has full access to all host network interfaces. Use only when necessary for performance or special network requirements.

None Network

Completely isolated—no network access.

BASH
# Run with no network
docker run -d --network none alpine sleep infinity
 
# Container has only loopback interface
docker exec <container> ip addr
# Only shows 'lo' interface

Overlay Network

For multi-host networking with Docker Swarm or Kubernetes:

BASH
# Create overlay network (requires Swarm mode)
docker network create --driver overlay my-overlay
 
# Used for distributed applications across hosts

Macvlan Network

Assign a MAC address to containers, making them appear as physical devices:

BASH
# Create macvlan network
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  macnet

Creating and Managing Networks

Creating Networks

BASH
# Create with default settings
docker network create mynetwork
 
# Create with specific subnet
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  mynetwork
 
# Create with IP range
docker network create \
  --subnet 192.168.0.0/24 \
  --ip-range 192.168.0.128/25 \
  --gateway 192.168.0.1 \
  mynetwork

Inspecting Networks

BASH
# View network details
docker network inspect mynetwork
 
# See connected containers
docker network inspect mynetwork --format '{{range .Containers}}{{.Name}} {{end}}'
 
# View network configuration
docker network inspect bridge --format '{{.IPAM.Config}}'

Connecting and Disconnecting

BASH
# Connect a running container to a network
docker network connect mynetwork mycontainer
 
# Connect with specific IP
docker network connect --ip 172.20.0.100 mynetwork mycontainer
 
# Disconnect from a network
docker network disconnect mynetwork mycontainer

Removing Networks

BASH
# Remove a network
docker network rm mynetwork
 
# Remove all unused networks
docker network prune

Note

You cannot remove a network that has connected containers. Disconnect or stop the containers first.

Container DNS

Docker provides automatic DNS resolution for containers on user-defined networks.

Automatic Service Discovery

BASH
# Create a network
docker network create app-network
 
# Start containers
docker run -d --name database --network app-network postgres:16
docker run -d --name backend --network app-network myapi
 
# Containers can reach each other by name
docker exec backend ping database
docker exec backend curl http://database:5432

DNS Resolution

BASH
# Inside the 'backend' container:
$ ping database
PING database (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.089 ms
 
$ cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

Network Aliases

Give containers additional DNS names:

BASH
# Create container with alias
docker run -d \
  --name postgres \
  --network app-network \
  --network-alias db \
  --network-alias database \
  postgres:16
 
# Both names resolve to the same container
docker exec backend ping db
docker exec backend ping database
docker exec backend ping postgres

Custom DNS Settings

BASH
# Use custom DNS servers
docker run -d \
  --dns 8.8.8.8 \
  --dns 8.8.4.4 \
  --dns-search example.com \
  myapp
 
# Set hostname
docker run -d --hostname myserver.local myapp

Port Publishing

Expose container ports to the host machine:

Basic Port Mapping

BASH
# Map container port 80 to host port 8080
docker run -d -p 8080:80 nginx
 
# Map to specific interface
docker run -d -p 127.0.0.1:8080:80 nginx
 
# Map multiple ports
docker run -d -p 80:80 -p 443:443 nginx
 
# Random host port
docker run -d -p 80 nginx
docker port <container>  # Shows assigned port

Port Protocols

BASH
# TCP (default)
docker run -d -p 8080:80/tcp nginx
 
# UDP
docker run -d -p 53:53/udp dns-server
 
# Both TCP and UDP
docker run -d -p 53:53/tcp -p 53:53/udp dns-server

Viewing Port Mappings

BASH
# Show port mappings for a container
docker port mycontainer
 
# Show all containers with ports
docker ps --format "table {{.Names}}\t{{.Ports}}"

Port Mapping Output

BASH
$ docker ps
CONTAINER ID   IMAGE   PORTS                                      NAMES
abc123         nginx   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   web
def456         redis   6379/tcp                                    cache

Container Communication Patterns

Containers on the Same Network

BASH
# Create network
docker network create backend
 
# Start database
docker run -d \
  --name postgres \
  --network backend \
  -e POSTGRES_PASSWORD=secret \
  postgres:16
 
# Start app that connects to database
docker run -d \
  --name api \
  --network backend \
  -e DATABASE_URL=postgres://postgres:secret@postgres:5432/app \
  myapi

Containers on Multiple Networks

BASH
# Create networks
docker network create frontend
docker network create backend
 
# API server on both networks
docker run -d \
  --name api \
  --network frontend \
  myapi
 
docker network connect backend api
 
# Web server on frontend only
docker run -d --name web --network frontend nginx
 
# Database on backend only
docker run -d --name db --network backend postgres:16
 
# API can reach both web and db
# Web cannot reach db directly

Network Segmentation

PLAINTEXT
┌─────────────────────────────────────┐
│           Frontend Network          │
│  ┌──────────┐      ┌──────────┐    │
│  │   web    │◄────►│   api    │    │
│  │  (nginx) │      │ (node)   │    │
│  └──────────┘      └────┬─────┘    │
└─────────────────────────┼──────────┘

┌─────────────────────────┼──────────┐
│           Backend Network│          │
│                    ┌────┴─────┐    │
│                    │   api    │    │
│                    │ (node)   │    │
│                    └────┬─────┘    │
│                         │          │
│                    ┌────┴─────┐    │
│                    │    db    │    │
│                    │(postgres)│    │
│                    └──────────┘    │
└─────────────────────────────────────┘

IPv6 Support

Enable IPv6 for containers:

BASH
# Create dual-stack network
docker network create \
  --ipv6 \
  --subnet 172.28.0.0/16 \
  --subnet 2001:db8::/64 \
  mynetwork-v6
 
# Run container with IPv6
docker run -d --network mynetwork-v6 nginx

Troubleshooting Networking

Debug Connectivity

BASH
# Check container's network settings
docker inspect --format='{{json .NetworkSettings.Networks}}' mycontainer
 
# See all network interfaces in container
docker exec mycontainer ip addr
 
# Check routing table
docker exec mycontainer ip route
 
# Test DNS resolution
docker exec mycontainer nslookup other-container
 
# Test connectivity
docker exec mycontainer ping other-container
docker exec mycontainer curl http://other-container:8080

Common Network Tools

BASH
# Install network tools in Alpine
docker exec mycontainer apk add --no-cache curl bind-tools iputils
 
# Install in Debian/Ubuntu
docker exec mycontainer apt-get update && apt-get install -y curl dnsutils iputils-ping

Debug Network Container

Use a debug container with all networking tools:

BASH
# Run a debug container on the same network
docker run -it --rm \
  --network mynetwork \
  nicolaka/netshoot \
  /bin/bash
 
# Now you have: curl, dig, nslookup, ping, tcpdump, etc.

Note

The nicolaka/netshoot image is a network troubleshooting container with all common tools pre-installed. It's invaluable for debugging network issues.

Check IPtables Rules

BASH
# View Docker's iptables rules (on host)
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v
 
# See Docker's network namespaces
sudo ls /var/run/docker/netns/

Network Security

Isolate Sensitive Containers

BASH
# Create internal network (no external access)
docker network create --internal secure-network
 
# Containers can communicate internally but not reach internet
docker run -d --network secure-network sensitive-app

Limit Container Communication

BASH
# Disable inter-container communication on default bridge
docker network create --opt com.docker.network.bridge.enable_icc=false isolated
 
# Containers must explicitly be linked to communicate

Use Specific IP Bindings

BASH
# BAD: Binds to all interfaces (exposed externally)
docker run -p 8080:80 nginx
 
# GOOD: Bind to localhost only
docker run -p 127.0.0.1:8080:80 nginx
 
# GOOD: Bind to specific interface
docker run -p 10.0.0.5:8080:80 nginx

Warning

By default, -p 8080:80 binds to 0.0.0.0, exposing the port on all network interfaces including public ones. Always specify the interface for sensitive services.

Network Performance

Use Host Network for Performance

BASH
# Host network eliminates NAT overhead
docker run --network host high-perf-app
 
# Useful for:
# - Network-intensive applications
# - Applications requiring many ports
# - Performance-critical scenarios

Optimize MTU

BASH
# Create network with custom MTU
docker network create --opt "com.docker.network.driver.mtu=1450" mynetwork
 
# Useful in cloud environments with encapsulation overhead

Quick Reference

CommandPurpose
docker network lsList networks
docker network createCreate a network
docker network rmRemove a network
docker network inspectView network details
docker network connectConnect container to network
docker network disconnectDisconnect from network
docker network pruneRemove unused networks

Network Driver Summary

DriverUse CaseIsolationPerformance
bridgeDefault, single hostGoodGood
hostMaximum performanceNoneBest
noneComplete isolationCompleteN/A
overlayMulti-host (Swarm)GoodModerate
macvlanPhysical network integrationVariesGood

In the next chapter, we'll explore how to manage data persistence with volumes and bind mounts.