L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Déploiement et opérations · SKILL.md

docker-networking

docker-networking

Use when configuring Docker container networking — bridge networks, overlay networks, macvlan, host networking, DNS resolution between containers, published ports, network isolation, container-to-container communication, load balancing with Docker, IPv6, custom network drivers, and network troubleshooting. Part of the docker-* skill family. OS-agnostic.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: docker-networking description: Use when configuring Docker container networking — bridge networks, overlay networks, macvlan, host networking, DNS resolution between containers, published ports, network isolation, container-to-container communication, load balancing with Docker, IPv6, custom network drivers, and network troubleshooting. Part of the docker-* skill family. OS-agnostic. family: docker disambiguation: Container networking itself on any host — bridge, overlay, macvlan, DNS, port publishing. Installing and running the daemon on a distro is ubuntu-docker-host or rhel-docker-host.

Docker Networking

OS-agnostic Docker networking. For core Docker concepts, see parent skill docker-fundamentals. For OS-specific setup, see ubuntu-docker-host or rhel-docker-host.


1. Network Drivers Overview

DriverScopeDNSUse Case
bridge (default)Single hostNo auto DNSIsolated single-host containers (not recommended for multi-container)
User-defined bridgeSingle hostYesStandard multi-container apps, development, production single-host
hostSingle hostN/AMaximum network performance, no port mapping overhead
noneSingle hostNoComplete network isolation, security-sensitive workloads
macvlanSingle hostNoContainers need real LAN IPs, legacy app integration
ipvlanSingle hostNoSimilar to macvlan but works when promiscuous mode is blocked
overlayMulti-hostYesDocker Swarm services, multi-host container communication

Default Bridge vs User-Defined Bridge

FeatureDefault bridgeUser-Defined Bridge
DNS resolution by nameNo (IP only)Yes (automatic)
Network aliasesNoYes
Automatic isolationNo (all containers share it)Yes (per-network)
Connect/disconnect liveNoYes
--link supportYes (legacy)Not needed (use DNS)
ConfigurableLimitedFull (subnet, gateway, MTU)
# List all networks
docker network ls

# Inspect a network
docker network inspect bridge

# See which containers are on a network
docker network inspect mynet --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}'

2. User-Defined Bridge Networks

Creating Networks

# Basic creation
docker network create mynet

# With specific subnet and gateway
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  mynet

# With IP range (allocatable range within subnet)
docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --ip-range 172.20.10.0/24 \
  --gateway 172.20.0.1 \
  mynet

# Internal network (no external/internet access)
docker network create --internal backend

# With custom MTU and other options
docker network create \
  --driver bridge \
  --opt com.docker.network.bridge.name=br-mynet \
  --opt com.docker.network.driver.mtu=9000 \
  mynet

Connecting Containers

# Run container on a specific network
docker run -d --name web --network mynet nginx:alpine

# Run with a static IP
docker run -d --name db --network mynet --ip 172.20.0.100 postgres:16-alpine

# Connect a running container to an additional network
docker network connect mynet existing-container

# Connect with a specific IP
docker network connect --ip 172.20.0.50 mynet existing-container

# Disconnect from a network
docker network disconnect mynet existing-container

DNS Resolution and Network Aliases

# Containers on user-defined bridges automatically resolve each other by name
docker network create app-net
docker run -d --name api --network app-net myapi:latest
docker run -d --name web --network app-net myweb:latest

# From 'web', 'api' resolves to the api container's IP:
# curl http://api:8080/health   <-- works automatically

# Network aliases — multiple names for one container
docker run -d --name api-v2 --network app-net --network-alias api myapi:v2

# Multiple containers with the same alias = round-robin DNS (basic load balancing)
docker run -d --name api-1 --network app-net --network-alias api myapi:latest
docker run -d --name api-2 --network app-net --network-alias api myapi:latest
docker run -d --name api-3 --network app-net --network-alias api myapi:latest
# Requests to 'api' rotate across api-1, api-2, api-3

Compose Networking

# compose.yaml — Compose creates a default network automatically
# named <project>_default. All services join it.
services:
  web:
    image: nginx:alpine
    networks:
      - frontend
      - backend
  api:
    image: myapi:latest
    networks:
      backend:
        aliases:
          - api-service
  db:
    image: postgres:16-alpine
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true    # no external access
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

3. Host Networking

# Container shares the host's network namespace — no port mapping needed
docker run -d --network host nginx:alpine
# Nginx is now directly on host port 80

# Check — container has no separate IP
docker inspect --format '{{.NetworkSettings.IPAddress}}' <container>
# Returns empty string — it uses the host's IP

When to Use Host Networking

ScenarioRecommendation
Maximum network performanceUse host — eliminates NAT overhead
Application binds to many dynamic portsUse host — avoids mapping hundreds of ports
Network monitoring / packet captureUse host — sees all host traffic
Standard web appsUse bridge — isolation is more important than marginal performance

Limitations

  • No port mapping (-p is ignored) — container binds directly to host ports
  • No network isolation — container sees all host network interfaces
  • Port conflicts with host services or other host-mode containers
  • Does not work on Docker Desktop for Mac/Windows (runs inside a VM)
  • Cannot connect to user-defined bridge networks simultaneously

4. Macvlan Networks

Macvlan gives each container its own MAC address and a real IP on the physical network. Other devices on the LAN can reach containers directly.

Basic Macvlan

# Enable promiscuous mode on parent interface
sudo ip link set eth0 promisc on

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

# Run container with a LAN IP
docker run -d --name web --network macnet --ip 192.168.1.50 nginx:alpine
# Container is reachable at 192.168.1.50 from any device on the LAN

802.1q Trunk Mode (VLAN Tagging)

# Create macvlan on a VLAN-tagged sub-interface
docker network create -d macvlan \
  --subnet=10.10.20.0/24 \
  --gateway=10.10.20.1 \
  -o parent=eth0.20 \
  macvlan20

docker network create -d macvlan \
  --subnet=10.10.30.0/24 \
  --gateway=10.10.30.1 \
  -o parent=eth0.30 \
  macvlan30

# Containers on different VLANs
docker run -d --name web --network macvlan20 --ip 10.10.20.10 nginx
docker run -d --name db --network macvlan30 --ip 10.10.30.10 postgres:16

Host-to-Macvlan Container Communication

The host cannot directly communicate with its own macvlan containers (by design — macvlan filters traffic between parent and sub-interfaces). Workaround:

# Create a macvlan sub-interface on the host
sudo ip link add macvlan-shim link eth0 type macvlan mode bridge
sudo ip addr add 192.168.1.200/32 dev macvlan-shim
sudo ip link set macvlan-shim up

# Add route to container subnet via the shim
sudo ip route add 192.168.1.50/32 dev macvlan-shim

Ipvlan (Alternative)

# L2 mode — like macvlan but shares parent MAC (no promiscuous mode needed)
docker network create -d ipvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  -o ipvlan_mode=l2 \
  ipvlan-net

# L3 mode — routing-based, no broadcast, better for large-scale
docker network create -d ipvlan \
  --subnet=10.10.0.0/24 \
  -o parent=eth0 \
  -o ipvlan_mode=l3 \
  ipvlan-l3

5. Overlay Networks

Overlay networks span multiple Docker hosts using VXLAN encapsulation. Requires Docker Swarm or an external key-value store.

Swarm Overlay

# Initialize Swarm (required for overlay)
docker swarm init --advertise-addr 10.0.0.1

# Create overlay network
docker network create -d overlay myoverlay

# Create service on overlay
docker service create --name web --network myoverlay --replicas 3 nginx:alpine

# Encrypted overlay (data plane encryption — AES-GCM)
docker network create -d overlay --opt encrypted myoverlay-enc

Attachable Overlay (Standalone Containers)

# By default, overlay networks are only for Swarm services.
# --attachable allows standalone containers to join.
docker network create -d overlay --attachable shared-overlay

# Standalone container joins the overlay
docker run -d --name standalone-app --network shared-overlay myapp:latest

Overlay with Custom Subnet

docker network create -d overlay \
  --subnet=10.100.0.0/16 \
  --gateway=10.100.0.1 \
  --opt com.docker.network.driver.mtu=1450 \
  production-overlay

Ingress Network

# The default 'ingress' overlay handles Swarm routing mesh.
# Published ports on any node route to the correct container.
docker service create --name web -p 80:80 --replicas 3 nginx:alpine
# Port 80 on ANY Swarm node reaches one of the 3 replicas.

# Bypass routing mesh (only listen on nodes running the task)
docker service create --name web \
  --publish mode=host,target=80,published=80 \
  --mode global \
  nginx:alpine

6. DNS and Service Discovery

Embedded DNS Server

Docker runs a built-in DNS server at 127.0.0.11 for all user-defined networks.

# Check DNS config inside a container
docker exec mycontainer cat /etc/resolv.conf
# nameserver 127.0.0.11
# options ndots:0

# Test name resolution
docker exec mycontainer nslookup api
docker exec mycontainer getent hosts api

DNS Resolution Rules

What ResolvesWhereHow
Container nameSame user-defined networkAutomatic
Network aliasSame user-defined networkAutomatic
Service nameSwarm overlayAutomatic (VIP or DNSRR)
Container nameDefault bridgeDoes NOT resolve
External hostnamesAll networksForwarded to host DNS

Custom DNS Configuration

# Set custom DNS servers for a container
docker run -d --name web \
  --dns 8.8.8.8 \
  --dns 8.8.4.4 \
  nginx:alpine

# Set DNS search domain
docker run -d --name web \
  --dns-search example.com \
  nginx:alpine
# Allows resolving 'api' as 'api.example.com'

# Set custom hostname
docker run -d --name web \
  --hostname web.example.com \
  nginx:alpine

# Add /etc/hosts entries
docker run -d --name web \
  --add-host db:10.0.0.5 \
  --add-host cache:10.0.0.6 \
  nginx:alpine

# host-gateway — resolve to host's IP (Docker 20.10+)
docker run -d --name web \
  --add-host host.docker.internal:host-gateway \
  nginx:alpine

Daemon-Level DNS Config

// /etc/docker/daemon.json
{
  "dns": ["8.8.8.8", "8.8.4.4"],
  "dns-search": ["example.com"],
  "dns-opts": ["timeout:2", "attempts:3"]
}

Swarm Service Discovery Modes

# VIP mode (default) — single virtual IP, Docker load-balances
docker service create --name api \
  --endpoint-mode vip \
  --replicas 3 \
  myapi:latest
# 'api' resolves to one VIP; Docker handles round-robin behind it

# DNSRR mode — DNS returns all task IPs, client picks
docker service create --name api \
  --endpoint-mode dnsrr \
  --replicas 3 \
  myapi:latest
# 'api' resolves to 3 IPs; client or external LB picks

7. Port Publishing

Basic Port Mapping

# Map host port 8080 to container port 80
docker run -d -p 8080:80 nginx:alpine

# Map to localhost only (not exposed externally)
docker run -d -p 127.0.0.1:8080:80 nginx:alpine

# Map to specific host interface
docker run -d -p 10.0.0.5:8080:80 nginx:alpine

# Container port only (random host port assigned)
docker run -d -p 80 nginx:alpine

# Check assigned port
docker port <container>

UDP and Protocol-Specific

# UDP port
docker run -d -p 5514:514/udp syslog-ng

# TCP and UDP on same port
docker run -d -p 53:53/tcp -p 53:53/udp bind9

# SCTP (Docker 20.10+)
docker run -d -p 3868:3868/sctp diameter-server

Port Ranges

# Map a range of ports
docker run -d -p 8000-8010:8000-8010 myapp

# Publish all EXPOSEd ports (random host ports)
docker run -d --publish-all myapp
docker run -d -P myapp    # shorthand

Compose Port Syntax

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"                    # host:container
      - "443:443"
      - "127.0.0.1:8080:80"       # localhost only
      - "9090-9095:9090-9095"      # range
      - "514:514/udp"              # UDP
      - target: 80                 # long syntax
        published: 8080
        protocol: tcp
        mode: host                 # Swarm: bypass routing mesh

Default Bind Address

// /etc/docker/daemon.json — change default bind from 0.0.0.0
{
  "ip": "127.0.0.1"
}
// Now -p 8080:80 binds to 127.0.0.1:8080 by default

8. Network Isolation

Internal Networks

# No outbound internet access — containers can only talk to each other
docker network create --internal isolated-net

docker run -d --name db --network isolated-net postgres:16-alpine
docker run -d --name cache --network isolated-net redis:7-alpine
# db and cache can reach each other, but neither can reach the internet

Network Segmentation Pattern (Frontend / Backend)

# compose.yaml — classic three-tier isolation
services:
  proxy:
    image: nginx:alpine
    ports:
      - "80:80"
    networks:
      - frontend

  api:
    image: myapi:latest
    networks:
      - frontend      # reachable by proxy
      - backend        # can reach db

  db:
    image: postgres:16-alpine
    networks:
      - backend        # only reachable by api

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true     # no internet access for db

Result: proxy cannot reach db directly. api bridges the two networks. db has no internet access.

Inter-Container Communication (ICC)

// /etc/docker/daemon.json — disable ICC on default bridge
{
  "icc": false
}
// Containers on default bridge cannot communicate unless explicitly --link'd
// User-defined networks are unaffected (use network isolation instead)

iptables and Docker

# Docker manages iptables rules automatically. Key chains:
# DOCKER-USER — insert custom rules here (survives Docker restarts)
# DOCKER — managed by Docker (do not modify)
# DOCKER-ISOLATION-STAGE-1/2 — network isolation

# Block external access to a published port (except from trusted IP)
sudo iptables -I DOCKER-USER -i eth0 -p tcp --dport 8080 \
  ! -s 10.0.0.0/8 -j DROP

# Block container-to-container across networks
sudo iptables -I DOCKER-USER -i br-abc123 -o br-def456 -j DROP

# Allow established/related connections
sudo iptables -I DOCKER-USER -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Persist rules
sudo iptables-save > /etc/iptables/rules.v4

Disable Docker's iptables Management

// /etc/docker/daemon.json — NOT recommended unless using external firewall
{
  "iptables": false
}
// You must then manually configure all NAT and forwarding rules

9. Container-to-Container Communication

Same Network (By Name)

# Containers on the same user-defined network resolve each other by name
docker network create app-net
docker run -d --name api --network app-net myapi:latest
docker run -d --name web --network app-net myweb:latest

# From web container:
docker exec web curl http://api:8080/health    # resolves 'api' via DNS
docker exec web ping api                        # also works

Cross-Network Communication

# Container on two networks can bridge communication
docker network create frontend
docker network create backend

docker run -d --name api --network frontend myapi:latest
docker network connect backend api
# 'api' is now on both frontend and backend

docker run -d --name web --network frontend myweb:latest
docker run -d --name db --network backend postgres:16-alpine

# web -> api (via frontend) -> db (via backend)
# web cannot reach db directly

Link (Legacy — Do Not Use)

# --link is deprecated. Do NOT use in new projects.
# docker run --link db:database myapp    # legacy
# Instead, use user-defined networks (automatic DNS, no ordering dependency)

Container-to-Host Communication

# From a container, reach the host machine
# Docker Desktop: host.docker.internal (built-in)
# Linux Docker Engine 20.10+:
docker run --add-host host.docker.internal:host-gateway myapp

# Or use the docker0 bridge gateway IP (usually 172.17.0.1)
docker exec mycontainer ip route | grep default

10. IPv6

Enable IPv6

// /etc/docker/daemon.json
{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80",
  "ip6tables": true,
  "experimental": true
}
# Restart Docker after editing daemon.json
sudo systemctl restart docker

Dual-Stack User-Defined Network

# Create a dual-stack network
docker network create \
  --ipv6 \
  --subnet 172.20.0.0/16 \
  --subnet fd00:dead:beef::/48 \
  dualstack-net

# Run container — gets both IPv4 and IPv6 addresses
docker run -d --name web --network dualstack-net nginx:alpine

# Verify
docker inspect web --format '{{range .NetworkSettings.Networks}}IPv4: {{.IPAddress}} IPv6: {{.GlobalIPv6Address}}{{end}}'

IPv6 Port Publishing

# Publish on IPv6
docker run -d -p "[::1]:8080:80" nginx:alpine        # IPv6 localhost only
docker run -d -p "[::]:8080:80" nginx:alpine          # all IPv6 interfaces

Compose IPv6

networks:
  dualstack:
    enable_ipv6: true
    ipam:
      config:
        - subnet: 172.20.0.0/16
        - subnet: fd00:dead:beef::/48

11. Network Troubleshooting

Inspecting Networks and Container IPs

# List all networks
docker network ls

# Detailed network info (connected containers, subnet, gateway)
docker network inspect mynet

# Get container's IP address
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container>

# Get all network details for a container
docker inspect -f '{{json .NetworkSettings.Networks}}' <container> | jq

# Which networks is a container on?
docker inspect -f '{{range $k, $v := .NetworkSettings.Networks}}{{$k}} {{end}}' <container>

# List containers on a specific network
docker network inspect mynet -f '{{range .Containers}}{{.Name}}: {{.IPv4Address}}{{"\n"}}{{end}}'

DNS Debugging

# Check resolv.conf inside container
docker exec <container> cat /etc/resolv.conf

# Test name resolution
docker exec <container> nslookup api
docker exec <container> getent hosts api
docker exec <container> dig api    # if dig is installed

# Check /etc/hosts
docker exec <container> cat /etc/hosts

# Verify embedded DNS is working
docker exec <container> nslookup google.com 127.0.0.11

# Common DNS issue: wrong network
docker exec <container> nslookup other-container
# Fails? Check they are on the same user-defined network.

Connectivity Testing

# Ping between containers
docker exec web ping -c 3 api

# Test TCP connectivity
docker exec web nc -zv api 8080

# HTTP test
docker exec web curl -s -o /dev/null -w "%{http_code}" http://api:8080/health

# Test from host to container
curl http://localhost:8080/health

# Check published port mapping
docker port <container>

Packet Capture (tcpdump)

# Install tcpdump in a running container (if not present)
docker exec -u root <container> apt-get update && apt-get install -y tcpdump
docker exec -u root <container> apk add tcpdump     # Alpine

# Capture traffic
docker exec <container> tcpdump -i eth0 -n port 80

# Capture and save to host
docker exec <container> tcpdump -i eth0 -w - port 80 > capture.pcap

Netshoot Sidecar (Recommended)

The nicolaka/netshoot image includes every network debugging tool — use it as a sidecar without modifying your containers.

# Attach to a container's network namespace
docker run -it --rm \
  --net container:<target-container> \
  nicolaka/netshoot

# Inside netshoot, you now have:
# tcpdump, curl, dig, nslookup, nmap, iperf3, mtr,
# netstat, ss, ip, iftop, drill, traceroute, and more

# Attach to a container's network AND PID namespace
docker run -it --rm \
  --net container:<target-container> \
  --pid container:<target-container> \
  nicolaka/netshoot

# Attach to host network
docker run -it --rm --net host nicolaka/netshoot

# Capture traffic on a specific network
docker run -it --rm --net mynet nicolaka/netshoot tcpdump -i eth0

iptables Debugging

# View Docker-managed iptables rules
sudo iptables -L -n -v
sudo iptables -t nat -L -n -v

# Check DOCKER-USER chain (custom rules)
sudo iptables -L DOCKER-USER -n -v

# Check network isolation rules
sudo iptables -L DOCKER-ISOLATION-STAGE-1 -n -v

# Watch rule hit counters in real-time
watch -n 1 'sudo iptables -L DOCKER-USER -n -v'

Common Issues and Fixes

ProblemCauseFix
Container can't resolve another by nameOn default bridge networkUse a user-defined bridge network
curl: (6) Could not resolve hostContainers on different networksConnect both to the same network
Port published but not reachableFirewall blocking on hostCheck ufw/firewalld/iptables rules
Port published but wrong interfaceBound to 0.0.0.0, expected specific IPUse -p 10.0.0.5:8080:80
Container can't reach internetOn --internal networkIntended. Move to non-internal network if access needed
Container can't reach host servicesNo route to host IPUse --add-host host.docker.internal:host-gateway
Macvlan container unreachable from hostMacvlan design (host-to-own-macvlan blocked)Create macvlan shim interface on host (see section 4)
DNS resolution slow (5s delay)IPv6 DNS query failing, falling back to IPv4Set --dns-opt single-request-reopen or fix IPv6 config
Overlay network not workingSwarm not initialized or ports blockedInit Swarm; open TCP 2377, TCP/UDP 7946, UDP 4789
Containers on same network can't communicateicc=false in daemon.jsonSet icc: true or use user-defined networks (unaffected)

Network Performance Testing

# iperf3 between containers
docker run -d --name iperf-server --network mynet networkstatic/iperf3 -s
docker run -it --rm --network mynet networkstatic/iperf3 -c iperf-server

# Measure latency
docker exec web ping -c 100 api | tail -1
# rtt min/avg/max/mdev = 0.030/0.045/0.120/0.015 ms

# Compare bridge vs host network performance
docker run -it --rm --network bridge networkstatic/iperf3 -c <host-ip>
docker run -it --rm --network host networkstatic/iperf3 -c <host-ip>

Quick Reference: Network Create Options

docker network create [OPTIONS] NETWORK

  --driver, -d        Driver (bridge, overlay, macvlan, ipvlan, none)
  --subnet            Subnet in CIDR format (e.g., 172.20.0.0/16)
  --ip-range          Allocatable IP range within subnet
  --gateway           Gateway for the subnet
  --ipv6              Enable IPv6
  --internal          No external connectivity
  --attachable        Allow standalone containers (overlay only)
  --opt, -o           Driver-specific options
  --label             Metadata labels


Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Using the default bridge network for multi-container appsNo DNS resolution between containers; must use IP addresses; no network isolationCreate custom bridge networks; containers resolve each other by service name automatically
Publishing all ports to host with -p 0.0.0.0:port:portExposes services to all network interfaces including public; bypasses host firewall on some setupsBind to specific interface: -p 127.0.0.1:port:port for local-only; use reverse proxy for external access
Using host networking mode for everythingNo network isolation; port conflicts between containers; container can access all host servicesUse host mode only when performance-critical (raw socket, multicast); default to bridge networks
Not creating network aliases for service discoveryContainers reference each other by container name which changes; refactoring breaks connectivityUse --network-alias or Compose service names for stable DNS; decouple container names from service identity
Hardcoding container IP addressesDocker assigns IPs dynamically; IPs change on restart; breaks after any container recreationUse DNS-based service discovery; never reference container IPs in configuration

Related Skills

TopicSkill
Core Docker concepts, CLI, Dockerfiledocker-fundamentals
Compose, cross-platform, AD mappingdocker-admin
Volumes, bind mounts, storage driversdocker-storage
Image scanning, rootless, CIS benchmarkdocker-security
CI/CD, multi-platform builds, registriesdocker-cicd
Advanced Compose patternsdocker-compose-patterns
Docker on Ubuntu 24.04ubuntu-docker-host
Podman/Docker on RHEL 9rhel-docker-host
Skills enregistrées