Compose文件 #

文件结构 #

yaml
version: '3.8'          # Compose文件版本

services:               # 服务定义
  service1:
    # 服务配置
  service2:
    # 服务配置

networks:               # 网络定义
  network1:
    # 网络配置

volumes:                # 数据卷定义
  volume1:
    # 数据卷配置

configs:                # 配置定义(Swarm模式)
  config1:
    # 配置

secrets:                # 密钥定义(Swarm模式)
  secret1:
    # 密钥

版本说明 #

版本 说明
3.8 最新版本,支持所有功能
3.x 支持Docker Engine 1.13.0+
2.x 支持Docker Engine 1.10.0+

服务配置 #

build #

构建配置。

yaml
services:
  app:
    build:
      context: .                    # 构建上下文
      dockerfile: Dockerfile        # Dockerfile路径
      args:                         # 构建参数
        - VERSION=1.0
      target: production            # 目标构建阶段
      labels:                       # 标签
        - "app=myapp"

image #

使用现有镜像。

yaml
services:
  web:
    image: nginx:alpine
    image: myregistry.com/myapp:v1.0

ports #

端口映射。

yaml
services:
  web:
    ports:
      - "80:80"                     # 指定端口
      - "443:443"                   # 多个端口
      - "127.0.0.1:8000:8000"       # 指定IP
      - "53:53/udp"                 # UDP端口
      - "9000-9005:9000-9005"       # 端口范围

expose #

暴露端口(仅容器间访问)。

yaml
services:
  web:
    expose:
      - "80"
      - "443"

volumes #

数据卷挂载。

yaml
services:
  app:
    volumes:
      - /host/path:/container/path          # 绑定挂载
      - volume-name:/container/path         # 命名卷
      - /container/path                     # 匿名卷
      - ./src:/app/src:ro                   # 只读挂载
      - type: volume                        # 长格式
        source: data
        target: /app/data
        read_only: true

volumes:
  volume-name:

environment #

环境变量。

yaml
services:
  app:
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
    # 或使用字典格式
    environment:
      NODE_ENV: production
      DB_HOST: db
      DB_PORT: 3306

env_file #

从文件加载环境变量。

yaml
services:
  app:
    env_file:
      - .env
      - .env.local
      - ./config/.env

depends_on #

服务依赖。

yaml
services:
  web:
    depends_on:
      - db
      - redis

  app:
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

networks #

网络配置。

yaml
services:
  app:
    networks:
      - frontend
      - backend

networks:
  frontend:
  backend:

restart #

重启策略。

yaml
services:
  app:
    restart: no              # 不重启
    restart: always          # 总是重启
    restart: on-failure      # 失败时重启
    restart: unless-stopped  # 除非手动停止

healthcheck #

健康检查。

yaml
services:
  app:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

command #

覆盖默认命令。

yaml
services:
  app:
    command: npm start
    command: ["npm", "start"]
    command: bundle exec thin -p 3000

entrypoint #

覆盖入口点。

yaml
services:
  app:
    entrypoint: /app/entrypoint.sh
    entrypoint: ["/app/entrypoint.sh"]

working_dir #

工作目录。

yaml
services:
  app:
    working_dir: /app

user #

运行用户。

yaml
services:
  app:
    user: node
    user: "1000:1000"

labels #

标签。

yaml
services:
  app:
    labels:
      - "com.example.description=My app"
      - "com.example.version=1.0"

container_name #

容器名称。

yaml
services:
  app:
    container_name: my-app

hostname #

主机名。

yaml
services:
  app:
    hostname: myhost

domainname #

域名。

yaml
services:
  app:
    domainname: example.com

extra_hosts #

添加hosts条目。

yaml
services:
  app:
    extra_hosts:
      - "myhost:192.168.1.100"
      - "otherhost:192.168.1.101"

dns #

DNS服务器。

yaml
services:
  app:
    dns:
      - 8.8.8.8
      - 8.8.4.4

privileged #

特权模式。

yaml
services:
  app:
    privileged: true

cap_add/cap_drop #

添加/删除能力。

yaml
services:
  app:
    cap_add:
      - NET_ADMIN
    cap_drop:
      - MKNOD

security_opt #

安全选项。

yaml
services:
  app:
    security_opt:
      - label:user:USER
      - no-new-privileges:true

ulimits #

资源限制。

yaml
services:
  app:
    ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000

sysctls #

内核参数。

yaml
services:
  app:
    sysctls:
      - net.core.somaxconn=1024
      - net.ipv4.tcp_syncookies=0

deploy #

部署配置(Swarm模式)。

yaml
services:
  app:
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
        delay: 10s
      rollback_config:
        parallelism: 1
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

网络配置 #

基本网络 #

yaml
networks:
  frontend:
  backend:

网络选项 #

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
    labels:
      - "env=production"

外部网络 #

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

数据卷配置 #

基本卷 #

yaml
volumes:
  data:
  logs:

卷选项 #

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

外部卷 #

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

完整示例 #

yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    container_name: my-web
    hostname: web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - web-logs:/var/log/nginx
    networks:
      - frontend
    depends_on:
      - app
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3
    labels:
      - "app=myapp"
      - "service=web"

  app:
    build:
      context: ./app
      dockerfile: Dockerfile
      args:
        - NODE_ENV=production
    container_name: my-app
    working_dir: /app
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
      - REDIS_HOST=redis
    env_file:
      - .env
    volumes:
      - app-data:/app/data
    networks:
      - frontend
      - backend
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: mysql:8.0
    container_name: my-db
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}
      MYSQL_DATABASE: mydb
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:alpine
    container_name: my-redis
    volumes:
      - redis-data:/data
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

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

volumes:
  app-data:
  mysql-data:
  redis-data:
  web-logs:

小结 #

本节详细学习了docker-compose.yml的配置:

  • 文件结构和版本
  • 服务配置选项
  • 网络配置
  • 数据卷配置
  • 完整配置示例

下一步 #

接下来,让我们学习 多容器应用编排,了解如何编排复杂的多容器应用。