Container networking enables communication between containers and with external systems. Networks provide the foundation for building multi-container applications where different components need to interact. Understanding how default and custom networks work is essential for designing secure, efficient, and maintainable containerized architectures.
Understanding Container Networks
Container networks create isolated communication channels where containers can discover and communicate with each other. Each network provides a virtual network interface with its own IP address space, DNS resolution, and routing rules. Containers connected to the same network can communicate directly, while containers on different networks remain isolated unless explicitly connected.
Networks abstract away the complexity of network configuration, providing simple naming-based discovery. Instead of managing IP addresses, containers can reference each other by name, and the network infrastructure handles resolution and routing automatically.
Default Network Behavior
When you don't explicitly define networks, containers automatically connect to a default network. This default network is created automatically and provides basic connectivity between all containers in the same application stack.
services:
web:
image: nginx:alpine
# Automatically joins default network
api:
image: node:18
# Also joins default network
# Can reach 'web' by name
database:
image: postgres:15
# Also on default network
# Can reach both 'web' and 'api' by name
The default network allows containers to communicate using their service names as hostnames. A container named web can be reached by other containers on the same network using the hostname web.
Default Network Naming
The default network receives an automatically generated name based on the project name and a network suffix.
services:
app:
image: myapp:latest
# Joins network named: <project>_default
# Example: myproject_default
Understanding the default network naming helps when debugging connectivity or integrating with external tools that need to reference the network.
Custom Network Definitions
Custom networks provide explicit control over network topology, isolation, and configuration. You define networks in the top-level networks section and reference them from containers.
services:
web:
image: nginx:alpine
networks:
- frontend
# Joins custom 'frontend' network
api:
image: node:18
networks:
- frontend
- backend
# Joins both networks
database:
image: postgres:15
networks:
- backend
# Only joins backend network
networks:
frontend:
# Frontend network definition
backend:
# Backend network definition
This configuration creates network isolation—web and database cannot communicate directly because they're on different networks. The api container acts as a bridge, connecting to both networks.
Network Drivers
Networks use drivers that determine their implementation and capabilities. The most common driver is bridge, which creates isolated networks on a single host.
networks:
app-network:
driver: bridge
# Default driver - creates bridge network
custom-bridge:
driver: bridge
driver_opts:
com.docker.network.bridge.name: custom0
# Bridge with custom options
The bridge driver is suitable for most single-host deployments and provides network isolation with good performance.
Bridge Network Configuration
Bridge networks support various configuration options that control their behavior.
networks:
configured-bridge:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-custom
com.docker.network.bridge.enable_icc: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
com.docker.network.bridge.host_binding_ipv4: "0.0.0.0"
com.docker.network.driver.mtu: "1500"
Driver options provide fine-grained control over bridge network characteristics, though defaults work well for most use cases.
Network IP Configuration
Networks can specify IP address ranges, subnets, and gateway addresses explicitly.
networks:
frontend:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
# Custom IP range for frontend network
backend:
driver: bridge
ipam:
config:
- subnet: 172.21.0.0/16
ip_range: 172.21.5.0/24
gateway: 172.21.0.1
# Backend network with restricted IP range
IPAM (IP Address Management) configuration controls how IP addresses are allocated within the network.
Multiple Subnet Configuration
Networks can have multiple subnets for advanced network topologies.
networks:
multi-subnet:
driver: bridge
ipam:
config:
- subnet: 172.22.0.0/24
gateway: 172.22.0.1
- subnet: 172.23.0.0/24
gateway: 172.23.0.1
# Network with two subnets
Multiple subnets enable complex networking scenarios where different address ranges serve different purposes.
Container Network Attachment
Containers can connect to multiple networks simultaneously, enabling sophisticated network topologies.
services:
proxy:
image: nginx:alpine
networks:
- public
- internal
# Connected to both networks
app:
image: myapp:latest
networks:
- internal
- database-net
# Connected to different network combination
db:
image: postgres:15
networks:
- database-net
# Connected only to database network
networks:
public:
internal:
database-net:
Multi-network attachment allows containers to participate in different network segments, controlling which containers can communicate.
Network Aliases
Containers can have multiple names (aliases) on a network, allowing them to be reached by different hostnames.
services:
web:
image: nginx:alpine
networks:
frontend:
aliases:
- webserver
- www
- frontend-lb
# Reachable as 'web', 'webserver', 'www', or 'frontend-lb'
networks:
frontend:
Aliases provide flexibility in how containers reference each other, supporting migration scenarios or standardized naming conventions.
Multiple Networks with Different Aliases
Containers can have different aliases on different networks.
services:
api:
image: api-server:latest
networks:
frontend:
aliases:
- api
- api-gateway
backend:
aliases:
- internal-api
- processor
# Different names on different networks
networks:
frontend:
backend:
This capability allows containers to present different identities to different network segments.
Static IP Address Assignment
Containers can receive static IP addresses instead of dynamic DHCP allocation.
services:
web:
image: nginx:alpine
networks:
frontend:
ipv4_address: 172.20.0.10
# Fixed IP address on frontend network
api:
image: node:18
networks:
frontend:
ipv4_address: 172.20.0.20
backend:
ipv4_address: 172.21.0.20
# Different static IPs on different networks
networks:
frontend:
ipam:
config:
- subnet: 172.20.0.0/16
backend:
ipam:
config:
- subnet: 172.21.0.0/16
Static IPs provide predictable addresses but reduce flexibility. They're useful when other systems need to reference containers by IP address.
IPv6 Network Support
Networks can support IPv6 addressing alongside or instead of IPv4.
networks:
ipv6-network:
driver: bridge
enable_ipv6: true
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
- subnet: 2001:db8:1::/64
gateway: 2001:db8:1::1
# Dual-stack network with IPv4 and IPv6
IPv6 support requires explicit enablement and appropriate subnet configuration.
Network Isolation and Segmentation
Different networks provide isolation between container groups, implementing security boundaries.
services:
# Public-facing tier
loadbalancer:
image: nginx:alpine
networks:
- public
# Application tier
webapp:
image: webapp:latest
networks:
- public
- app-tier
api:
image: api:latest
networks:
- app-tier
- data-tier
# Data tier
database:
image: postgres:15
networks:
- data-tier
cache:
image: redis:7
networks:
- data-tier
networks:
public:
# External-facing network
app-tier:
# Application logic network
data-tier:
# Data storage network
internal: true
# Isolated from external access
This three-tier architecture uses networks to enforce separation between public, application, and data layers.
Internal Networks
Internal networks prevent external connectivity, keeping communication strictly between containers.
networks:
internal-net:
driver: bridge
internal: true
# No external connectivity
# Only container-to-container communication
external-net:
driver: bridge
internal: false
# Default - allows external access
Internal networks enhance security by ensuring certain containers cannot reach or be reached from outside the container environment.
Network Labels
Networks can have labels for organization, documentation, and filtering.
networks:
frontend:
driver: bridge
labels:
- "com.example.description=Frontend network"
- "com.example.department=engineering"
- "com.example.environment=production"
backend:
driver: bridge
labels:
com.example.description: "Backend services network"
com.example.tier: "application"
Labels help organize and identify networks, especially in environments with many networks.
External Networks
External networks reference existing networks created outside the current configuration.
services:
app:
image: myapp:latest
networks:
- existing-network
networks:
existing-network:
external: true
# References pre-existing network
# Does not create or manage it
External networks enable connecting to infrastructure created by other tools or configurations.
External Network Naming
External networks can specify the actual network name if it differs from the reference name.
networks:
my-network:
external: true
name: actual_network_name
# References network named 'actual_network_name'
# But refers to it as 'my-network' in this configuration
This naming flexibility helps integrate with existing network infrastructure.
Network Priority and Order
When containers connect to multiple networks, the order can affect routing and default gateway selection.
services:
app:
image: myapp:latest
networks:
- primary-network
- secondary-network
# Primary-network becomes default route
networks:
primary-network:
secondary-network:
The first network typically becomes the default route, though specific behavior depends on the container runtime and network configuration.
DNS Configuration
Networks provide DNS resolution for container names, and you can customize DNS settings.
services:
app:
image: myapp:latest
networks:
- app-network
dns:
- 8.8.8.8
- 8.8.4.4
# Custom DNS servers
dns_search:
- example.com
- internal.example.com
# DNS search domains
networks:
app-network:
Custom DNS configuration allows containers to resolve external hostnames through specific DNS servers or search specific domains.
Network-Level DNS
Networks themselves can have DNS configuration that applies to all connected containers.
networks:
custom-network:
driver: bridge
driver_opts:
com.docker.network.bridge.name: custom-br0
com.docker.network.bridge.enable_ip_masquerade: "true"
ipam:
driver: default
config:
- subnet: 172.25.0.0/16
gateway: 172.25.0.1
aux_addresses:
host: 172.25.0.2
Network-level configuration affects all containers on that network, providing consistent settings.
Network Attachability
Networks can control whether containers can attach at runtime versus only at creation time.
networks:
attachable-net:
driver: bridge
attachable: true
# Containers can attach after creation
fixed-net:
driver: bridge
attachable: false
# Containers must attach at creation time
Attachability affects operational flexibility and security characteristics of the network.
Network MTU Configuration
Maximum Transmission Unit (MTU) settings control packet size on the network.
networks:
optimized-network:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: "1450"
# Custom MTU for specific network requirements
MTU configuration helps optimize network performance for specific environments, particularly those using overlay networks or VPNs.
Link-Local IP Addresses
Networks can be configured to use link-local addressing for special use cases.
networks:
link-local:
driver: bridge
ipam:
config:
- subnet: 169.254.0.0/16
gateway: 169.254.0.1
# Link-local addressing
Link-local addresses provide unique addressing without external configuration, useful for certain network topologies.
Network Encryption
Some network drivers support encryption for secure container communication.
networks:
secure-network:
driver: overlay
driver_opts:
encrypted: "true"
# Encrypted network traffic between containers
Encryption protects data in transit between containers, important for sensitive workloads.
Container Network Modes
Beyond standard bridge networks, containers can use alternative network modes.
services:
host-mode:
image: myapp:latest
network_mode: "host"
# Uses host's network directly
# No network isolation
none-mode:
image: isolated:latest
network_mode: "none"
# No network connectivity
# Completely isolated
container-mode:
image: sidecar:latest
network_mode: "container:other-container"
# Shares network with another container
Alternative network modes serve specific use cases like high-performance networking or complete isolation.
Service Discovery
Networks provide automatic service discovery through DNS, allowing containers to find each other by name.
services:
web:
image: nginx:alpine
networks:
- app-network
# Accessible as 'web' within app-network
api:
image: node:18
networks:
- app-network
# Can reach web at 'http://web'
worker:
image: python:3.11
networks:
- app-network
# Can reach api at 'http://api'
networks:
app-network:
DNS-based discovery eliminates the need for hardcoded IP addresses, making configurations portable and maintainable.
Network Debugging and Inspection
Understanding network configuration helps diagnose connectivity issues.
services:
debug:
image: nicolaka/netshoot
networks:
- app-network
- data-network
# Debug container with network tools
# Can inspect connectivity from within networks
networks:
app-network:
data-network:
Dedicated debug containers provide tools for testing network connectivity, DNS resolution, and routing from within the container network environment.
Network Performance Considerations
Different network configurations have different performance characteristics.
networks:
high-performance:
driver: bridge
driver_opts:
com.docker.network.driver.mtu: "9000"
# Jumbo frames for better throughput
standard:
driver: bridge
# Default settings for typical workloads
Performance tuning through MTU and other settings optimizes networks for specific workload characteristics.
Port Publishing and Networks
Containers on networks can publish ports to make them accessible from outside the network.
services:
web:
image: nginx:alpine
networks:
- frontend
ports:
- "80:80"
- "443:443"
# Publishes ports to host
# Accessible from outside the network
networks:
frontend:
Port publishing creates mappings between host ports and container ports, enabling external access to containerized applications.
Network Naming Conventions
Following naming conventions for networks improves configuration clarity.
networks:
frontend-net:
# Clear tier indication
backend-net:
# Matches architectural layer
data-net:
# Purpose-based naming
myapp-public:
# Application-prefixed naming
myapp-internal:
# Combines app name and scope
Consistent naming helps teams understand network topology at a glance.
Multi-Network Communication Patterns
Complex applications use multiple networks to create sophisticated communication patterns.
services:
# Edge services
edge-router:
image: traefik:latest
networks:
- external
- dmz
# DMZ services
web-frontend:
image: webapp:latest
networks:
- dmz
- app-tier
# Application services
api-server:
image: api:latest
networks:
- app-tier
- service-mesh
background-worker:
image: worker:latest
networks:
- service-mesh
- data-tier
# Data services
primary-db:
image: postgres:15
networks:
- data-tier
cache-server:
image: redis:7
networks:
- data-tier
networks:
external:
# Public internet-facing
dmz:
# Demilitarized zone
app-tier:
# Application logic
service-mesh:
# Internal service communication
data-tier:
internal: true
# Isolated data layer
This pattern creates multiple security zones with controlled connectivity between tiers.
Network Subnet Planning
Proper subnet planning prevents IP address conflicts and enables growth.
networks:
prod-frontend:
ipam:
config:
- subnet: 10.1.0.0/24
# 254 addresses for production frontend
prod-backend:
ipam:
config:
- subnet: 10.2.0.0/24
# 254 addresses for production backend
dev-network:
ipam:
config:
- subnet: 10.100.0.0/16
# Large range for development
test-network:
ipam:
config:
- subnet: 10.200.0.0/16
# Large range for testing
Systematic subnet allocation prevents overlap and provides room for scaling.
Gateway Configuration
Custom gateway addresses control routing within networks.
networks:
custom-routing:
driver: bridge
ipam:
config:
- subnet: 172.30.0.0/16
gateway: 172.30.0.1
# Gateway at .1 (conventional)
alternate-gateway:
driver: bridge
ipam:
config:
- subnet: 172.31.0.0/16
gateway: 172.31.0.254
# Gateway at .254 (alternate convention)
Gateway configuration affects how packets route within and out of the network.
Auxiliary Addresses
Networks can reserve IP addresses for specific purposes.
networks:
managed-network:
ipam:
config:
- subnet: 172.28.0.0/16
gateway: 172.28.0.1
aux_addresses:
router: 172.28.0.2
dns: 172.28.0.3
monitoring: 172.28.0.4
# Reserved addresses for infrastructure
Auxiliary addresses prevent automatic allocation of IPs needed for infrastructure components.
Network Scope
Networks have scope that determines their visibility and lifecycle.
networks:
local-scope:
driver: bridge
scope: local
# Visible only on single host
swarm-scope:
driver: overlay
scope: swarm
# Visible across cluster
Scope affects how networks are distributed and managed across infrastructure.
Practical Network Architecture Patterns
Real-world applications combine these concepts into cohesive network architectures.
services:
# Public load balancer
nginx:
image: nginx:alpine
networks:
public:
ipv4_address: 172.16.1.10
frontend:
ports:
- "80:80"
- "443:443"
# Frontend application servers
webapp-1:
image: webapp:latest
networks:
frontend:
aliases:
- webapp
backend:
webapp-2:
image: webapp:latest
networks:
frontend:
aliases:
- webapp
backend:
# Backend API servers
api-1:
image: api:latest
networks:
backend:
aliases:
- api
database-tier:
api-2:
image: api:latest
networks:
backend:
aliases:
- api
database-tier:
# Database cluster
db-primary:
image: postgres:15
networks:
database-tier:
ipv4_address: 172.16.4.10
aliases:
- db-master
db-replica:
image: postgres:15
networks:
database-tier:
ipv4_address: 172.16.4.11
aliases:
- db-slave
# Cache layer
redis-primary:
image: redis:7
networks:
backend:
database-tier:
# Monitoring
prometheus:
image: prom/prometheus
networks:
- monitoring
- frontend
- backend
- database-tier
networks:
public:
driver: bridge
ipam:
config:
- subnet: 172.16.1.0/24
gateway: 172.16.1.1
labels:
com.example.tier: "public"
com.example.description: "Public-facing network"
frontend:
driver: bridge
ipam:
config:
- subnet: 172.16.2.0/24
labels:
com.example.tier: "frontend"
backend:
driver: bridge
ipam:
config:
- subnet: 172.16.3.0/24
labels:
com.example.tier: "backend"
database-tier:
driver: bridge
internal: true
ipam:
config:
- subnet: 172.16.4.0/24
gateway: 172.16.4.1
labels:
com.example.tier: "data"
com.example.internal: "true"
monitoring:
driver: bridge
ipam:
config:
- subnet: 172.16.5.0/24
labels:
com.example.tier: "monitoring"
This comprehensive example demonstrates multi-tier architecture with proper network segmentation, static IPs where needed, aliases for load balancing, internal networks for data isolation, and cross-tier monitoring access.