Skip to content

Docker Compose 文件格式参考

本文档提供 Docker Compose 文件格式的完整参考,包括所有配置选项、语法规则和最佳实践。

目录

  1. 文件规范
  2. 顶层元素
  3. 服务配置详解
  4. 网络配置详解
  5. 卷配置详解
  6. 高级特性

文件规范

版本历史

版本Docker 版本主要特性
3.819.03.0+支持 max_replicas_per_node
3.718.06.0+支持 initoom_score_adj
3.618.02.0+支持 start_period
3.517.12.0+支持 namedriver 选项
3.417.09.0+支持 order 在更新配置中
3.317.06.0+支持 build.labels
3.217.04.0+支持 cache_fromnetwork
3.11.13.1+支持 secretshealthcheck
3.01.13.0+支持 Swarm 模式
2.417.12.0+支持 start_period
2.317.06.0+支持 targetcache_from
2.21.13.0+支持 init
2.11.12.0+支持 pids_limituserns_mode
2.01.10.0+引入网络和卷
1.01.9.0+初始版本

文件结构

yaml
version: "3.8"  # 必需:指定 Compose 文件版本

services:       # 必需:定义服务
  service_name:
    # 服务配置

networks:       # 可选:定义网络
  network_name:
    # 网络配置

volumes:        # 可选:定义卷
  volume_name:
    # 卷配置

configs:        # 可选:定义配置(Swarm)
  config_name:
    # 配置定义

secrets:        # 可选:定义密钥(Swarm)
  secret_name:
    # 密钥定义

顶层元素

services

定义应用的服务组件。

yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
  
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret

networks

定义应用使用的网络。

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

volumes

定义应用使用的卷。

yaml
volumes:
  db-data:
    driver: local
  cache:
    driver: local

configs

定义 Swarm 配置对象。

yaml
configs:
  nginx-config:
    file: ./nginx.conf
  app-config:
    external: true

secrets

定义 Swarm 密钥对象。

yaml
secrets:
  db-password:
    file: ./secrets/db-password.txt
  api-key:
    external: true

服务配置详解

build

指定构建配置。

yaml
services:
  web:
    build:
      # 上下文路径
      context: ./web
      
      # Dockerfile 路径
      dockerfile: Dockerfile.prod
      
      # 构建参数
      args:
        - NODE_ENV=production
        - VERSION=1.0.0
      
      # 缓存源
      cache_from:
        - myapp/web:latest
        - myapp/web:cache
      
      # 标签
      labels:
        - "com.example.description=Web application"
        - "com.example.department=IT"
      
      # 多阶段构建目标
      target: production
      
      # 构建网络
      network: host
      
      # 构建秘密
      secrets:
        - npmrc
      
      # SSH 代理
      ssh:
        - default
      
      # 额外主机
      extra_hosts:
        - "npm.registry:192.168.1.100"
      
      # 隔离
      isolation: default
      
      # 平台
      platforms:
        - linux/amd64
        - linux/arm64

image

指定镜像。

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

command

覆盖默认命令。

yaml
services:
  web:
    image: nginx:alpine
    # 字符串形式
    command: nginx -g 'daemon off;'
    # 列表形式
    command: ["nginx", "-g", "daemon off;"]

entrypoint

覆盖默认入口点。

yaml
services:
  web:
    image: nginx:alpine
    entrypoint: /docker-entrypoint.sh
    # 或
    entrypoint: ["/docker-entrypoint.sh"]

environment

设置环境变量。

yaml
services:
  web:
    image: myapp:latest
    # 键值对形式
    environment:
      NODE_ENV: production
      DEBUG: "false"
      PORT: 3000
    
    # 列表形式
    environment:
      - NODE_ENV=production
      - DEBUG=false
      - PORT=3000
    
    # 引用环境变量
    environment:
      - NODE_ENV=${NODE_ENV:-production}
      - API_KEY=${API_KEY}

env_file

从文件加载环境变量。

yaml
services:
  web:
    image: myapp:latest
    env_file:
      - .env
      - .env.local
    # 或带路径
    env_file:
      - ./config/.env

ports

暴露端口。

yaml
services:
  web:
    image: nginx:alpine
    # 短语法
    ports:
      - "3000"           # 仅暴露容器端口
      - "8080:80"        # 主机:容器
      - "127.0.0.1:8080:80"  # 绑定地址
      - "8080-8090:80-90"    # 范围
      - "8080:80/udp"    # 指定协议
    
    # 长语法
    ports:
      - target: 80
        published: 8080
        protocol: tcp
        mode: host
      - target: 443
        published: 8443
        protocol: tcp
        mode: host

expose

暴露端口(不发布到主机)。

yaml
services:
  web:
    image: myapp:latest
    expose:
      - "3000"
      - "8080"

volumes

挂载卷。

yaml
services:
  web:
    image: myapp:latest
    # 短语法
    volumes:
      - /var/lib/mysql                    # 命名卷
      - /opt/data:/var/lib/mysql          # 绑定挂载
      - ./cache:/tmp/cache:ro             # 只读
      - data-volume:/var/lib/mysql        # 使用命名卷
    
    # 长语法
    volumes:
      - type: volume
        source: mydata
        target: /data
        volume:
          nocopy: true
      
      - type: bind
        source: ./config
        target: /config
        read_only: true
      
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 100M
          mode: 1770

networks

连接网络。

yaml
services:
  web:
    image: myapp:latest
    networks:
      - frontend
      - backend
    # 带配置
    networks:
      frontend:
        aliases:
          - web-alias
      backend:
        ipv4_address: 172.16.238.10

depends_on

配置服务依赖。

yaml
services:
  web:
    image: myapp:latest
    # 简单依赖
    depends_on:
      - db
      - redis
    
    # 带条件(Compose v3+)
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

healthcheck

配置健康检查。

yaml
services:
  web:
    image: myapp:latest
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
      disable: false

deploy

Swarm 部署配置。

yaml
services:
  web:
    image: myapp:latest
    deploy:
      # 模式
      mode: replicated  # 或 global
      
      # 副本数
      replicas: 3
      
      # 标签
      labels:
        - "com.example.description=Web service"
      
      # 更新配置
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
        order: start-first
      
      # 回滚配置
      rollback_config:
        parallelism: 1
        delay: 10s
        failure_action: pause
      
      # 重启策略
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      
      # 放置约束
      placement:
        constraints:
          - node.role == worker
          - node.labels.zone == public
        preferences:
          - spread: node.labels.rack
        max_replicas_per_node: 1
      
      # 资源限制
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
          pids: 100
        reservations:
          cpus: '0.25'
          memory: 256M
          generic_resources:
            - discrete_resource_spec:
                kind: nvidia.com/gpu
                value: 2
      
      #  endpoint_mode
      endpoint_mode: vip  # 或 dnsrr

logging

配置日志。

yaml
services:
  web:
    image: myapp:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
        labels: "service_name,environment"
        env: "OS_VERSION"

restart

配置重启策略。

yaml
services:
  web:
    image: myapp:latest
    restart: unless-stopped
    # 选项: no, always, on-failure, unless-stopped

security_opt

配置安全选项。

yaml
services:
  web:
    image: myapp:latest
    security_opt:
      - no-new-privileges:true
      - seccomp:unconfined
      - apparmor:docker-default

sysctls

配置内核参数。

yaml
services:
  web:
    image: myapp:latest
    sysctls:
      - net.core.somaxconn=1024
      - net.ipv4.ip_forward=1

ulimits

配置资源限制。

yaml
services:
  web:
    image: myapp:latest
    ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000
      as:
        soft: 102400000
        hard: 102400000

user

配置用户。

yaml
services:
  web:
    image: myapp:latest
    user: "1000:1000"
    # 或
    user: appuser

working_dir

配置工作目录。

yaml
services:
  web:
    image: myapp:latest
    working_dir: /app

domainname / hostname / ipc / mac_address / privileged / read_only / shm_size / stdin_open / tty / stop_signal / stop_grace_period

其他配置选项。

yaml
services:
  web:
    image: myapp:latest
    domainname: example.com
    hostname: web-server
    ipc: host
    mac_address: 02:42:ac:11:65:43
    privileged: false
    read_only: true
    shm_size: 64M
    stdin_open: true
    tty: true
    stop_signal: SIGTERM
    stop_grace_period: 30s

网络配置详解

基本配置

yaml
networks:
  frontend:
    driver: bridge
  
  backend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: backend-bridge
      com.docker.network.bridge.enable_icc: "true"
      com.docker.network.bridge.enable_ip_masquerade: "true"
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          ip_range: 172.28.5.0/24
          gateway: 172.28.5.254
          aux_addresses:
            host1: 172.28.1.5
            host2: 172.28.1.6
      options:
        foo: bar
    internal: true
    attachable: true
    labels:
      - "com.example.description=Backend network"

外部网络

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

Overlay 网络

yaml
networks:
  overlay-network:
    driver: overlay
    attachable: true
    driver_opts:
      encrypted: "true"

卷配置详解

基本配置

yaml
volumes:
  db-data:
    driver: local
  
  app-data:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.1.100,rw
      device: ":/path/to/dir"
    labels:
      - "com.example.description=Application data"

外部卷

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

命名卷

yaml
volumes:
  named-volume:
    driver: local
    driver_opts:
      size: 10GiB

高级特性

扩展字段

yaml
x-common-variables: &common-variables
  TZ: Asia/Shanghai
  LANG: en_US.UTF-8

x-common-deploy: &common-deploy
  restart_policy:
    condition: on-failure
    delay: 5s
    max_attempts: 3

services:
  web:
    image: myapp:latest
    environment:
      <<: *common-variables
      APP_NAME: web
    deploy:
      <<: *common-deploy
      replicas: 3

变量插值

yaml
services:
  web:
    image: "${WEB_IMAGE:-nginx:alpine}"
    ports:
      - "${WEB_PORT:-80}:80"
    environment:
      - NODE_ENV=${NODE_ENV:-production}
      - DATABASE_URL=${DATABASE_URL:?required}

多文件配置

yaml
# docker-compose.yml
version: '3.8'
services:
  web:
    image: nginx:alpine

# docker-compose.prod.yml
version: '3.8'
services:
  web:
    deploy:
      replicas: 3

# 使用
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

完整示例

yaml
version: '3.8'

services:
  nginx:
    image: nginx:1.25.3-alpine
    container_name: nginx-proxy
    hostname: nginx
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    volumes:
      - type: bind
        source: ./nginx/nginx.conf
        target: /etc/nginx/nginx.conf
        read_only: true
      - type: bind
        source: ./nginx/ssl
        target: /etc/nginx/ssl
        read_only: true
      - type: volume
        source: nginx-cache
        target: /var/cache/nginx
    networks:
      - frontend
    depends_on:
      web:
        condition: service_healthy
      api:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
        reservations:
          cpus: '0.25'
          memory: 128M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    logging:
      driver: json-file
      options:
        max-size: 10m
        max-file: 3
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`example.com`)"

  web:
    build:
      context: ./web
      dockerfile: Dockerfile
      args:
        - NODE_ENV=production
      target: production
      cache_from:
        - myapp/web:latest
    image: myapp/web:${VERSION:-latest}
    environment:
      NODE_ENV: production
      API_URL: http://api:8080
      REDIS_URL: redis://redis:6379
    volumes:
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 100M
    networks:
      - frontend
      - backend
    depends_on:
      api:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
        order: start-first
      restart_policy:
        condition: any
        delay: 5s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - node.role == worker
        preferences:
          - spread: node.labels.zone

networks:
  frontend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: frontend
  backend:
    driver: bridge
    internal: true
    driver_opts:
      com.docker.network.bridge.name: backend
      com.docker.network.bridge.enable_icc: "true"
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1

volumes:
  nginx-cache:
    driver: local

下一步

基于 MIT 许可发布