Compose网络与存储 #

网络配置 #

默认网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
  app:
    image: myapp

# 自动创建 default 网络
# 项目名称_default

自定义网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - frontend

  app:
    image: myapp
    networks:
      - frontend
      - backend

  db:
    image: mysql
    networks:
      - backend

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

网络配置选项 #

yaml
networks:
  frontend:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1400
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1
          ip_range: 172.20.1.0/24
    labels:
      - "env=production"

外部网络 #

yaml
version: '3.8'

services:
  web:
    image: nginx
    networks:
      - external-network

networks:
  external-network:
    external: true
    name: my-external-network

服务网络配置 #

yaml
services:
  app:
    image: myapp
    networks:
      frontend:
        aliases:
          - myapp
          - api
      backend:
        ipv4_address: 172.20.0.10

存储配置 #

命名卷 #

yaml
version: '3.8'

services:
  db:
    image: mysql:8.0
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:
    driver: local

卷配置选项 #

yaml
volumes:
  db-data:
    driver: local
    driver_opts:
      type: none
      device: /data/mysql
      o: bind
    labels:
      - "app=myapp"

外部卷 #

yaml
version: '3.8'

services:
  db:
    image: mysql:8.0
    volumes:
      - external-data:/var/lib/mysql

volumes:
  external-data:
    external: true
    name: my-external-volume

绑定挂载 #

yaml
version: '3.8'

services:
  app:
    image: myapp
    volumes:
      - ./app:/app
      - ./config:/app/config:ro
      - ./logs:/app/logs

tmpfs挂载 #

yaml
version: '3.8'

services:
  app:
    image: myapp
    tmpfs:
      - /tmp
      - /var/cache

网络隔离 #

多层网络架构 #

yaml
version: '3.8'

services:
  # 公开服务
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    networks:
      - public
    depends_on:
      - frontend

  # 前端服务
  frontend:
    image: myapp-frontend
    networks:
      - public
      - internal
    depends_on:
      - api

  # API服务
  api:
    image: myapp-api
    networks:
      - internal
      - data
    depends_on:
      - db
      - redis

  # 数据服务
  db:
    image: mysql:8.0
    networks:
      - data

  redis:
    image: redis:alpine
    networks:
      - data

networks:
  public:
    driver: bridge
  internal:
    driver: bridge
    internal: true
  data:
    driver: bridge
    internal: true

网络访问控制 #

yaml
version: '3.8'

services:
  # 只能被内部访问
  db:
    image: mysql:8.0
    networks:
      - backend

  # 可以访问外部
  api:
    image: myapp
    networks:
      - backend
      - frontend

  # 公开访问
  web:
    image: nginx
    ports:
      - "80:80"
    networks:
      - frontend

networks:
  backend:
    internal: true
  frontend:

数据管理 #

数据卷共享 #

yaml
version: '3.8'

services:
  app:
    image: myapp
    volumes:
      - shared-data:/data

  worker:
    image: myapp-worker
    volumes:
      - shared-data:/data

volumes:
  shared-data:

数据卷容器模式 #

yaml
version: '3.8'

services:
  data:
    image: alpine
    volumes:
      - /data
    command: ["tail", "-f", "/dev/null"]

  app:
    image: myapp
    volumes_from:
      - data

开发环境配置 #

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app                    # 代码同步
      - /app/node_modules         # 匿名卷,避免覆盖
      - app-cache:/root/.cache    # 缓存持久化
    environment:
      - NODE_ENV=development

volumes:
  app-cache:

配置管理 #

使用configs(Swarm模式) #

yaml
version: '3.8'

services:
  app:
    image: myapp
    configs:
      - source: app_config
        target: /app/config.yml
      - source: nginx_config
        target: /etc/nginx/nginx.conf

configs:
  app_config:
    file: ./config/app.yml
  nginx_config:
    file: ./config/nginx.conf

使用secrets(Swarm模式) #

yaml
version: '3.8'

services:
  db:
    image: mysql:8.0
    secrets:
      - db_password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

环境变量管理 #

yaml
version: '3.8'

services:
  app:
    image: myapp
    env_file:
      - .env
      - .env.local
    environment:
      - NODE_ENV=${NODE_ENV:-production}
      - DB_HOST=${DB_HOST:-db}
      - DB_PORT=${DB_PORT:-3306}

完整示例 #

生产环境配置 #

yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - nginx-logs:/var/log/nginx
    networks:
      - frontend
    depends_on:
      - app
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M

  app:
    image: myapp:${APP_VERSION:-latest}
    volumes:
      - app-data:/app/data
      - app-logs:/app/logs
    networks:
      - frontend
      - backend
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
      - DB_NAME=${DB_NAME:-mydb}
      - REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
      replicas: 2

  db:
    image: mysql:8.0
    volumes:
      - mysql-data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
    networks:
      - backend
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${DB_NAME:-mydb}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G

  redis:
    image: redis:alpine
    volumes:
      - redis-data:/data
    networks:
      - backend
    command: redis-server --appendonly yes
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M

networks:
  frontend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
  backend:
    driver: bridge
    internal: true
    ipam:
      config:
        - subnet: 172.21.0.0/16

volumes:
  app-data:
    driver: local
  app-logs:
    driver: local
  mysql-data:
    driver: local
  redis-data:
    driver: local
  nginx-logs:
    driver: local

小结 #

本节学习了Docker Compose的网络和存储配置:

  • 网络配置选项
  • 存储配置选项
  • 网络隔离实现
  • 数据管理策略
  • 配置和密钥管理
  • 生产环境完整示例

下一步 #

接下来,让我们学习 Docker Hub,了解Docker公共仓库的使用方法。