docker-compose-networking

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Compose Networking

Docker Compose 网络配置

Master network configuration and service communication patterns in Docker Compose for building secure, scalable multi-container applications.
掌握Docker Compose中的网络配置和服务通信模式,以构建安全、可扩展的多容器应用。

Default Bridge Network

默认桥接网络

Docker Compose automatically creates a default bridge network for all services in a compose file:
yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    # Can reach backend using service name as hostname

  backend:
    image: node:18-alpine
    command: node server.js
    # Accessible at hostname 'backend' from frontend

  database:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    # Accessible at hostname 'database' from backend
In this setup:
  • All services can communicate using service names as hostnames
  • Frontend can reach backend at
    http://backend:3000
  • Backend can reach database at
    postgres://database:5432
  • Only frontend's port 80 is exposed to host
Docker Compose会自动为compose文件中的所有服务创建一个默认桥接网络:
yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    # 可通过服务名称作为主机名访问backend

  backend:
    image: node:18-alpine
    command: node server.js
    # 从frontend可通过主机名'backend'访问

  database:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    # 从backend可通过主机名'database'访问
在此配置中:
  • 所有服务可通过服务名称作为主机名进行通信
  • Frontend可通过
    http://backend:3000
    访问backend
  • Backend可通过
    postgres://database:5432
    访问database
  • 仅frontend的80端口暴露给宿主机

Custom Bridge Networks

自定义桥接网络

Define custom networks for service isolation and segmentation:
yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    networks:
      - frontend-network
    ports:
      - "80:80"

  api:
    image: node:18-alpine
    networks:
      - frontend-network
      - backend-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - backend-network
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    networks:
      - backend-network
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

networks:
  frontend-network:
    driver: bridge
  backend-network:
    driver: bridge
    internal: true

volumes:
  db-data:
  redis-data:
Network isolation:
  • Frontend can only reach API
  • Frontend cannot reach database or cache directly
  • API can reach all services
  • Backend network is internal (no external access)
定义自定义网络以实现服务隔离和分段:
yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    networks:
      - frontend-network
    ports:
      - "80:80"

  api:
    image: node:18-alpine
    networks:
      - frontend-network
      - backend-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - backend-network
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    networks:
      - backend-network
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

networks:
  frontend-network:
    driver: bridge
  backend-network:
    driver: bridge
    internal: true

volumes:
  db-data:
  redis-data:
网络隔离说明:
  • Frontend仅能访问API
  • Frontend无法直接访问database或cache
  • API可访问所有服务
  • Backend网络为内部网络(无外部访问权限)

Network Aliases

网络别名

Configure multiple hostnames for service discovery:
yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      public:
        aliases:
          - website
          - www
          - web-server
      internal:
        aliases:
          - web-internal

  api:
    image: node:18-alpine
    networks:
      public:
        aliases:
          - api-server
          - backend
      internal:
        aliases:
          - api-internal
    depends_on:
      - database

  database:
    image: postgres:15-alpine
    networks:
      internal:
        aliases:
          - db
          - postgres
          - primary-db
    environment:
      POSTGRES_PASSWORD: secret

networks:
  public:
    driver: bridge
  internal:
    driver: bridge
    internal: true
Services can be reached by any of their aliases:
  • http://website
    ,
    http://www
    ,
    http://web-server
    all reach web service
  • postgresql://db:5432
    ,
    postgresql://postgres:5432
    both reach database
配置多个主机名以实现服务发现:
yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      public:
        aliases:
          - website
          - www
          - web-server
      internal:
        aliases:
          - web-internal

  api:
    image: node:18-alpine
    networks:
      public:
        aliases:
          - api-server
          - backend
      internal:
        aliases:
          - api-internal
    depends_on:
      - database

  database:
    image: postgres:15-alpine
    networks:
      internal:
        aliases:
          - db
          - postgres
          - primary-db
    environment:
      POSTGRES_PASSWORD: secret

networks:
  public:
    driver: bridge
  internal:
    driver: bridge
    internal: true
服务可通过其任意别名访问:
  • http://website
    http://www
    http://web-server
    均可访问web服务
  • postgresql://db:5432
    postgresql://postgres:5432
    均可访问database

Static IP Addresses

静态IP地址

Assign fixed IP addresses for services requiring stable networking:
yaml
version: '3.8'

services:
  loadbalancer:
    image: nginx:alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.10
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

  app-1:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.11
    environment:
      APP_ID: "1"

  app-2:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.12
    environment:
      APP_ID: "2"

  app-3:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.13
    environment:
      APP_ID: "3"

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.20
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.1.1

volumes:
  pgdata:
为需要稳定网络的服务分配固定IP地址:
yaml
version: '3.8'

services:
  loadbalancer:
    image: nginx:alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.10
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

  app-1:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.11
    environment:
      APP_ID: "1"

  app-2:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.12
    environment:
      APP_ID: "2"

  app-3:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.13
    environment:
      APP_ID: "3"

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.20
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.1.1

volumes:
  pgdata:

External Networks

外部网络

Connect to existing Docker networks created outside Compose:
yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
      - shared-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge

  shared-network:
    external: true
    name: company-shared-network

volumes:
  pgdata:
Create external network first:
bash
docker network create company-shared-network
docker compose up -d
连接到在Compose外部创建的现有Docker网络:
yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
      - shared-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge

  shared-network:
    external: true
    name: company-shared-network

volumes:
  pgdata:
需先创建外部网络:
bash
docker network create company-shared-network
docker compose up -d

Host Network Mode

主机网络模式

Use host networking for maximum performance (Linux only):
yaml
version: '3.8'

services:
  high-performance-app:
    image: myapp:latest
    network_mode: "host"
    environment:
      BIND_ADDRESS: "0.0.0.0"
      PORT: "8080"
    # No port mapping needed - directly uses host's network stack

  monitoring:
    image: prometheus:latest
    network_mode: "host"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.listen-address=0.0.0.0:9090'

volumes:
  prometheus-data:
Note: Host networking bypasses Docker network isolation and is typically used for monitoring tools or high-throughput applications.
使用主机网络以获得最佳性能(仅适用于Linux):
yaml
version: '3.8'

services:
  high-performance-app:
    image: myapp:latest
    network_mode: "host"
    environment:
      BIND_ADDRESS: "0.0.0.0"
      PORT: "8080"
    # 无需端口映射 - 直接使用宿主机的网络栈

  monitoring:
    image: prometheus:latest
    network_mode: "host"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.listen-address=0.0.0.0:9090'

volumes:
  prometheus-data:
注意:主机网络会绕过Docker网络隔离,通常用于监控工具或高吞吐量应用。

Service Discovery and DNS

服务发现与DNS

Configure DNS resolution and service discovery:
yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
    dns:
      - 8.8.8.8
      - 8.8.4.4
    dns_search:
      - company.local
    extra_hosts:
      - "legacy-api.company.local:192.168.1.100"
      - "auth-service.company.local:192.168.1.101"
    environment:
      DATABASE_HOST: database.company.local

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        aliases:
          - database.company.local
          - db.company.local
    hostname: primary-database
    domainname: company.local
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-company-app

volumes:
  pgdata:
配置DNS解析和服务发现:
yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
    dns:
      - 8.8.8.8
      - 8.8.4.4
    dns_search:
      - company.local
    extra_hosts:
      - "legacy-api.company.local:192.168.1.100"
      - "auth-service.company.local:192.168.1.101"
    environment:
      DATABASE_HOST: database.company.local

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        aliases:
          - database.company.local
          - db.company.local
    hostname: primary-database
    domainname: company.local
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-company-app

volumes:
  pgdata:

Link Containers (Legacy)

链接容器(旧版)

While
links
is deprecated, understanding it helps migrate legacy configurations:
yaml
version: '3.8'

services:
  # Modern approach - use networks instead
  web:
    image: nginx:alpine
    networks:
      - app-network
    depends_on:
      - api

  api:
    image: node:18-alpine
    networks:
      - app-network
    depends_on:
      - database
    environment:
      # Use service name as hostname
      DATABASE_URL: postgresql://database:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret

networks:
  app-network:
    driver: bridge
虽然
links
已被弃用,但了解它有助于迁移旧版配置:
yaml
version: '3.8'

services:
  # 现代方式 - 使用网络替代
  web:
    image: nginx:alpine
    networks:
      - app-network
    depends_on:
      - api

  api:
    image: node:18-alpine
    networks:
      - app-network
    depends_on:
      - database
    environment:
      # 使用服务名称作为主机名
      DATABASE_URL: postgresql://database:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret

networks:
  app-network:
    driver: bridge

Multi-Network Architecture

多网络架构

Complex applications with multiple isolated networks:
yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    networks:
      - public
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - api

  frontend:
    image: react-app:latest
    networks:
      - public
      - frontend-tier
    environment:
      API_URL: http://api:3000

  api:
    image: node-api:latest
    networks:
      - frontend-tier
      - backend-tier
    environment:
      DATABASE_URL: postgresql://postgres:5432/app
      REDIS_URL: redis://cache:6379
      QUEUE_URL: amqp://rabbitmq:5672
    depends_on:
      - database
      - cache
      - queue

  worker:
    image: node-worker:latest
    networks:
      - backend-tier
    environment:
      DATABASE_URL: postgresql://postgres:5432/app
      QUEUE_URL: amqp://rabbitmq:5672
    depends_on:
      - database
      - queue
    deploy:
      replicas: 3

  database:
    image: postgres:15-alpine
    networks:
      - backend-tier
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    networks:
      - backend-tier
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

  queue:
    image: rabbitmq:3-management-alpine
    networks:
      - backend-tier
      - management
    ports:
      - "15672:15672"  # Management UI
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: secret
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq

  monitoring:
    image: prometheus:latest
    networks:
      - management
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus

networks:
  public:
    driver: bridge
  frontend-tier:
    driver: bridge
    internal: true
  backend-tier:
    driver: bridge
    internal: true
  management:
    driver: bridge

volumes:
  pgdata:
  redis-data:
  rabbitmq-data:
  prometheus-data:
Network segmentation:
  • Public: Internet-facing services (nginx, frontend)
  • Frontend-tier: Frontend and API communication
  • Backend-tier: API, workers, databases, cache, queue
  • Management: Monitoring and administration tools
具有多个隔离网络的复杂应用:
yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    networks:
      - public
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - api

  frontend:
    image: react-app:latest
    networks:
      - public
      - frontend-tier
    environment:
      API_URL: http://api:3000

  api:
    image: node-api:latest
    networks:
      - frontend-tier
      - backend-tier
    environment:
      DATABASE_URL: postgresql://postgres:5432/app
      REDIS_URL: redis://cache:6379
      QUEUE_URL: amqp://rabbitmq:5672
    depends_on:
      - database
      - cache
      - queue

  worker:
    image: node-worker:latest
    networks:
      - backend-tier
    environment:
      DATABASE_URL: postgresql://postgres:5432/app
      QUEUE_URL: amqp://rabbitmq:5672
    depends_on:
      - database
      - queue
    deploy:
      replicas: 3

  database:
    image: postgres:15-alpine
    networks:
      - backend-tier
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    networks:
      - backend-tier
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

  queue:
    image: rabbitmq:3-management-alpine
    networks:
      - backend-tier
      - management
    ports:
      - "15672:15672"  # 管理UI
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: secret
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq

  monitoring:
    image: prometheus:latest
    networks:
      - management
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus

networks:
  public:
    driver: bridge
  frontend-tier:
    driver: bridge
    internal: true
  backend-tier:
    driver: bridge
    internal: true
  management:
    driver: bridge

volumes:
  pgdata:
  redis-data:
  rabbitmq-data:
  prometheus-data:
网络分段说明:
  • Public:面向互联网的服务(nginx、frontend)
  • Frontend-tier:Frontend与API通信网络
  • Backend-tier:API、worker、数据库、缓存、队列所在网络
  • Management:监控和管理工具所在网络

Port Publishing Strategies

端口发布策略

Control how services expose ports:
yaml
version: '3.8'

services:
  # Short syntax - host:container
  web:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    networks:
      - public

  # Long syntax with protocol specification
  api:
    image: node:18-alpine
    ports:
      - target: 3000
        published: 3000
        protocol: tcp
        mode: host
    networks:
      - app-network

  # Random host port
  app:
    image: myapp:latest
    ports:
      - "3000"  # Docker assigns random host port
    networks:
      - app-network

  # Bind to specific host interface
  admin:
    image: admin-panel:latest
    ports:
      - "127.0.0.1:8080:80"  # Only accessible from localhost
    networks:
      - admin-network

  # UDP protocol
  dns:
    image: bind9:latest
    ports:
      - "53:53/udp"
      - "53:53/tcp"
    networks:
      - dns-network

  # Range of ports
  streaming:
    image: rtmp-server:latest
    ports:
      - "1935:1935"
      - "8080-8089:8080-8089"
    networks:
      - streaming-network

networks:
  public:
  app-network:
  admin-network:
    internal: true
  dns-network:
  streaming-network:
控制服务暴露端口的方式:
yaml
version: '3.8'

services:
  # 简短语法 - 宿主机端口:容器端口
  web:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    networks:
      - public

  # 带协议指定的完整语法
  api:
    image: node:18-alpine
    ports:
      - target: 3000
        published: 3000
        protocol: tcp
        mode: host
    networks:
      - app-network

  # 随机宿主机端口
  app:
    image: myapp:latest
    ports:
      - "3000"  # Docker会分配随机宿主机端口
    networks:
      - app-network

  # 绑定到特定宿主机接口
  admin:
    image: admin-panel:latest
    ports:
      - "127.0.0.1:8080:80"  # 仅可从本地访问
    networks:
      - admin-network

  # UDP协议
  dns:
    image: bind9:latest
    ports:
      - "53:53/udp"
      - "53:53/tcp"
    networks:
      - dns-network

  # 端口范围
  streaming:
    image: rtmp-server:latest
    ports:
      - "1935:1935"
      - "8080-8089:8080-8089"
    networks:
      - streaming-network

networks:
  public:
  app-network:
  admin-network:
    internal: true
  dns-network:
  streaming-network:

Container Communication Patterns

容器通信模式

Request-Response Pattern

请求-响应模式

yaml
version: '3.8'

services:
  gateway:
    image: nginx:alpine
    networks:
      - frontend
    ports:
      - "80:80"
    volumes:
      - ./nginx-gateway.conf:/etc/nginx/nginx.conf:ro

  service-a:
    image: service-a:latest
    networks:
      - frontend
      - backend
    environment:
      SERVICE_B_URL: http://service-b:8080
      DATABASE_URL: postgresql://db:5432/service_a

  service-b:
    image: service-b:latest
    networks:
      - frontend
      - backend
    environment:
      DATABASE_URL: postgresql://db:5432/service_b

  database:
    image: postgres:15-alpine
    networks:
      - backend
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

volumes:
  pgdata:
yaml
version: '3.8'

services:
  gateway:
    image: nginx:alpine
    networks:
      - frontend
    ports:
      - "80:80"
    volumes:
      - ./nginx-gateway.conf:/etc/nginx/nginx.conf:ro

  service-a:
    image: service-a:latest
    networks:
      - frontend
      - backend
    environment:
      SERVICE_B_URL: http://service-b:8080
      DATABASE_URL: postgresql://db:5432/service_a

  service-b:
    image: service-b:latest
    networks:
      - frontend
      - backend
    environment:
      DATABASE_URL: postgresql://db:5432/service_b

  database:
    image: postgres:15-alpine
    networks:
      - backend
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

volumes:
  pgdata:

Pub-Sub Pattern

发布-订阅模式

yaml
version: '3.8'

services:
  publisher:
    image: publisher:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
    depends_on:
      - redis

  subscriber-1:
    image: subscriber:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
      SUBSCRIBER_ID: "1"
    depends_on:
      - redis

  subscriber-2:
    image: subscriber:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
      SUBSCRIBER_ID: "2"
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    networks:
      - messaging
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

networks:
  messaging:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.enable_icc: "true"

volumes:
  redis-data:
yaml
version: '3.8'

services:
  publisher:
    image: publisher:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
    depends_on:
      - redis

  subscriber-1:
    image: subscriber:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
      SUBSCRIBER_ID: "1"
    depends_on:
      - redis

  subscriber-2:
    image: subscriber:latest
    networks:
      - messaging
    environment:
      REDIS_URL: redis://redis:6379
      SUBSCRIBER_ID: "2"
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    networks:
      - messaging
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

networks:
  messaging:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.enable_icc: "true"

volumes:
  redis-data:

Network Troubleshooting Configuration

网络故障排查配置

Enable debugging and monitoring:
yaml
version: '3.8'

services:
  app:
    image: myapp:latest
    networks:
      app-network:
        aliases:
          - primary-app
    cap_add:
      - NET_ADMIN
      - NET_RAW

  debug:
    image: nicolaka/netshoot:latest
    networks:
      - app-network
    command: sleep infinity
    cap_add:
      - NET_ADMIN
      - NET_RAW
    stdin_open: true
    tty: true

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        aliases:
          - db
    environment:
      POSTGRES_PASSWORD: secret

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.enable_ip_masquerade: "true"
      com.docker.network.driver.mtu: "1500"
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
Debug commands:
bash
undefined
启用调试和监控:
yaml
version: '3.8'

services:
  app:
    image: myapp:latest
    networks:
      app-network:
        aliases:
          - primary-app
    cap_add:
      - NET_ADMIN
      - NET_RAW

  debug:
    image: nicolaka/netshoot:latest
    networks:
      - app-network
    command: sleep infinity
    cap_add:
      - NET_ADMIN
      - NET_RAW
    stdin_open: true
    tty: true

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        aliases:
          - db
    environment:
      POSTGRES_PASSWORD: secret

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.enable_ip_masquerade: "true"
      com.docker.network.driver.mtu: "1500"
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
故障排查命令:
bash
undefined

Enter debug container

进入调试容器

docker compose exec debug bash
docker compose exec debug bash

Test connectivity

测试连通性

Check DNS resolution

检查DNS解析

nslookup app dig app
nslookup app dig app

Network scanning

网络扫描

nmap -p- app
nmap -p- app

Trace route

路由跟踪

traceroute app
traceroute app

Monitor traffic

流量监控

tcpdump -i eth0 -n
undefined
tcpdump -i eth0 -n
undefined

IPv6 Networking

IPv6网络

Enable IPv6 support:
yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      - ipv6-network
    ports:
      - "80:80"

  api:
    image: node:18-alpine
    networks:
      ipv6-network:
        ipv6_address: 2001:db8:1::10

  database:
    image: postgres:15-alpine
    networks:
      ipv6-network:
        ipv6_address: 2001:db8:1::20
    environment:
      POSTGRES_PASSWORD: secret

networks:
  ipv6-network:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
        - subnet: 2001:db8:1::/64
启用IPv6支持:
yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      - ipv6-network
    ports:
      - "80:80"

  api:
    image: node:18-alpine
    networks:
      ipv6-network:
        ipv6_address: 2001:db8:1::10

  database:
    image: postgres:15-alpine
    networks:
      ipv6-network:
        ipv6_address: 2001:db8:1::20
    environment:
      POSTGRES_PASSWORD: secret

networks:
  ipv6-network:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
        - subnet: 2001:db8:1::/64

When to Use This Skill

何时使用此技能

Use docker-compose-networking when you need to:
  • Configure custom network topologies for multi-container applications
  • Implement network segmentation and service isolation
  • Set up service discovery and inter-service communication
  • Design secure network architectures with frontend/backend separation
  • Configure static IP addresses for services
  • Connect to external Docker networks
  • Implement complex microservices communication patterns
  • Troubleshoot network connectivity issues
  • Configure DNS resolution and hostname aliases
  • Set up pub-sub or message queue architectures
  • Enable IPv6 networking
  • Optimize network performance with host networking
  • Configure port publishing and exposure strategies
当你需要以下操作时,使用docker-compose-networking:
  • 为多容器应用配置自定义网络拓扑
  • 实现网络分段和服务隔离
  • 设置服务发现和服务间通信
  • 设计带有前后端分离的安全网络架构
  • 为服务配置静态IP地址
  • 连接到外部Docker网络
  • 实现复杂的微服务通信模式
  • 排查网络连通性问题
  • 配置DNS解析和主机名别名
  • 设置发布-订阅或消息队列架构
  • 启用IPv6网络
  • 使用主机网络优化网络性能
  • 配置端口发布和暴露策略

Best Practices

最佳实践

  1. Use Custom Networks for Isolation: Always create custom networks instead of relying solely on the default network for better security and organization.
  2. Implement Network Segmentation: Separate frontend, backend, and data tiers into different networks to limit attack surface.
  3. Use Internal Networks: Mark backend networks as
    internal: true
    to prevent external access to sensitive services like databases.
  4. Prefer Service Names Over IPs: Use Docker's built-in DNS and service names instead of hardcoding IP addresses for maintainability.
  5. Configure Health Checks: Implement health checks to ensure services are ready before routing traffic to them.
  6. Use Network Aliases: Define meaningful aliases for services to support multiple naming conventions and easier migration.
  7. Avoid Host Networking Unless Necessary: Use bridge networks by default; host networking should only be used for specific performance requirements.
  8. Document Network Architecture: Clearly comment your network design and document which services can communicate with each other.
  9. Use Depends_on Wisely: Combine
    depends_on
    with health checks to ensure services start in the correct order.
  10. Implement Least Privilege: Only expose ports that absolutely need to be accessible from outside the Docker network.
  11. Use Environment Variables for URLs: Configure service endpoints through environment variables for flexibility across environments.
  12. Test Network Isolation: Regularly verify that services can only communicate through intended network paths.
  13. Configure Appropriate MTU: Set MTU values based on your network infrastructure to avoid fragmentation issues.
  14. Use External Networks for Shared Resources: When multiple Compose projects need to communicate, use external networks rather than duplicating services.
  15. Monitor Network Performance: Use tools like
    docker stats
    and dedicated monitoring containers to track network usage and identify bottlenecks.
  1. 使用自定义网络实现隔离:始终创建自定义网络,而非仅依赖默认网络,以提升安全性和组织性。
  2. 实现网络分段:将前端、后端和数据层分离到不同网络,以缩小攻击面。
  3. 使用内部网络:将后端网络标记为
    internal: true
    ,以防止外部访问数据库等敏感服务。
  4. 优先使用服务名称而非IP:使用Docker内置的DNS和服务名称,而非硬编码IP地址,以提升可维护性。
  5. 配置健康检查:实现健康检查,确保服务准备就绪后再将流量路由到它们。
  6. 使用网络别名:为服务定义有意义的别名,以支持多种命名约定和简化迁移。
  7. 除非必要,否则避免使用主机网络:默认使用桥接网络;仅在特定性能需求下使用主机网络。
  8. 记录网络架构:清晰注释你的网络设计,并记录哪些服务可以相互通信。
  9. 合理使用Depends_on:将
    depends_on
    与健康检查结合使用,确保服务按正确顺序启动。
  10. 实现最小权限原则:仅暴露绝对需要从Docker网络外部访问的端口。
  11. 使用环境变量配置URL:通过环境变量配置服务端点,以提升跨环境的灵活性。
  12. 测试网络隔离:定期验证服务仅能通过预期的网络路径通信。
  13. 配置适当的MTU:根据你的网络基础设施设置MTU值,以避免分片问题。
  14. 使用外部网络共享资源:当多个Compose项目需要通信时,使用外部网络而非重复服务。
  15. 监控网络性能:使用
    docker stats
    等工具和专用监控容器跟踪网络使用情况,识别瓶颈。

Common Pitfalls

常见陷阱

  1. Exposing All Services Publicly: Don't publish ports for services that should only be accessed internally; use networks instead of port publishing.
  2. Hardcoding IP Addresses: Avoid static IP addresses unless absolutely necessary; rely on service discovery instead.
  3. Using Default Network Only: Not creating custom networks misses opportunities for proper segmentation and isolation.
  4. Ignoring Network Modes: Using the wrong network mode (bridge vs host vs overlay) for your use case can cause connectivity or performance issues.
  5. Missing Network Dependencies: Not properly configuring
    depends_on
    can cause services to fail when trying to connect to unavailable services.
  6. Overusing Host Networking: Using
    network_mode: host
    unnecessarily breaks container isolation and portability.
  7. Not Using Internal Networks: Failing to mark backend networks as internal leaves databases and sensitive services exposed.
  8. Mixing Network Modes: Trying to publish ports or connect to networks when using
    network_mode: host
    causes configuration errors.
  9. Circular Network Dependencies: Creating network dependencies that form a circle prevents containers from starting properly.
  10. Ignoring DNS Configuration: Not configuring DNS properly can cause name resolution failures in containerized applications.
  11. Subnet Conflicts: Using IP ranges that conflict with host or other Docker networks causes routing issues.
  12. Not Testing Network Policies: Assuming network isolation works without testing can leave security vulnerabilities.
  13. Exposing Management Interfaces: Publishing management ports (like RabbitMQ, Redis, PostgreSQL) without authentication or IP restrictions.
  14. Using Links Instead of Networks: The deprecated
    links
    feature should be replaced with modern network configuration.
  15. Ignoring Network Driver Options: Not configuring driver options like MTU or IP masquerade can cause subtle connectivity problems in production.
  1. 公开所有服务:不要为仅需内部访问的服务发布端口;使用网络替代端口发布。
  2. 硬编码IP地址:除非绝对必要,否则避免使用静态IP地址;依赖服务发现。
  3. 仅使用默认网络:不创建自定义网络会错失适当分段和隔离的机会。
  4. 忽略网络模式:为你的使用场景选择错误的网络模式(桥接 vs 主机 vs 覆盖)会导致连通性或性能问题。
  5. 缺少网络依赖:未正确配置
    depends_on
    会导致服务尝试连接不可用的服务时失败。
  6. 过度使用主机网络:不必要地使用
    network_mode: host
    会破坏容器隔离和可移植性。
  7. 不使用内部网络:未将后端网络标记为内部网络会使数据库和敏感服务暴露在外。
  8. 混合网络模式:在使用
    network_mode: host
    时尝试发布端口或连接到网络会导致配置错误。
  9. 循环网络依赖:形成循环的网络依赖会阻止容器正常启动。
  10. 忽略DNS配置:未正确配置DNS会导致容器化应用中的名称解析失败。
  11. 子网冲突:使用与宿主机或其他Docker网络冲突的IP范围会导致路由问题。
  12. 不测试网络策略:假设网络隔离正常工作而不进行测试会留下安全漏洞。
  13. 暴露管理接口:发布管理端口(如RabbitMQ、Redis、PostgreSQL)而不进行身份验证或IP限制。
  14. 使用Links而非网络:已弃用的
    links
    功能应替换为现代网络配置。
  15. 忽略网络驱动选项:未配置MTU或IP伪装等驱动选项会导致生产环境中出现细微的连通性问题。

Resources

资源

Official Documentation

官方文档

Network Troubleshooting

网络故障排查

Architecture Patterns

架构模式

Tools

工具