Docker Compose基础

Docker Compose基础

概述

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具,通过 YAML 配置文件一次性管理多个容器的启动、网络和存储。本文档涵盖 Compose 配置文件的完整参数说明和常用配置示例。

核心概念

  • services:定义所有容器服务(核心必选)
  • networks:定义自定义网络,用于服务间通信
  • volumes:定义持久化数据卷,用于数据持久化
  • configs / secrets:Swarm 模式专用配置管理

配置文件核心结构

version: '3.8'  # Compose 文件格式版本

services:        # 服务定义(核心)
  ...

networks:        # 网络定义
  ...

volumes:         # 卷定义
  ...

configs:         # Swarm 模式配置
  ...

secrets:         # Swarm 模式密钥
  ...

x-*:             # 自定义扩展字段
  ...

顶层参数说明

参数 说明
version Compose 文件格式版本(推荐 3.8+,适配 Docker 20.10+)
services 定义所有容器服务(核心必选模块)
networks 定义自定义网络,支持多种驱动(bridge、overlay、host)
volumes 定义持久化数据卷,支持本地卷、NFS、CIFS 等
configs Swarm 模式专用,共享非敏感配置文件
secrets Swarm 模式专用,存储敏感信息(密码、密钥)
x-* 自定义扩展字段(如 x-common-env),Compose 会忽略

基础运行示例

services:
  nginx:
    image: nginx
    container_name: nginx
    restart: unless-stopped
    environment:
      ENV_TEST: 123456
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html

资源限制

内存限制

mem_limit: 2000M

CPU 和内存限制(推荐)

deploy:
  resources:
    limits:
      cpus: "1"
      memory: 1G
    reservations:
      cpus: "0.5"
      memory: 512M

文件打开数限制

sysctls:
  - net.core.somaxconn=65535
ulimits:
  nofile:
    soft: 100000
    hard: 100000

网络配置

使用已有网络

# 使用已有自定义网络
network_mode: app-network

# 使用 host 网络
network_mode: host

# 使用 bridge 网络
network_mode: bridge

自定义网络(不指定网段)

networks:
  - app-network

networks:
  app-network:
    driver: bridge

自定义网络并指定网段

networks:
  - app-network

networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16
          gateway: 172.30.0.1

自定义网络并指定容器 IP

services:
  nginx:
    networks:
      app_net:
        ipv4_address: 172.30.0.2

networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16
          gateway: 172.30.0.1

持久化配置

宿主机目录挂载

volumes:
  - ./conf:/etc/nginx/conf.d
  - ./conf/default.conf:/etc/nginx/conf.d/default.conf

使用命名卷

volumes:
  - nginx_conf:/etc/nginx/conf.d

volumes:
  nginx_conf:

指定存储名称和驱动

volumes:
  - nginx_conf:/etc/nginx/conf.d

volumes:
  nginx_conf:
    name: conf
    driver: local

使用已有存储

volumes:
  - existing_volume:/app/data

volumes:
  existing_volume:
    external: true
    name: pre-existing-volume-name

挂载自定义目录(bind mount)

volumes:
  - nginx_test:/etc/nginx/conf.d

volumes:
  nginx_test:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /data/nginx/conf.d

远程挂载(NFS)

volumes:
  nfs_volume:
    driver: local
    driver_opts:
      type: nfs
      device: ":/nfs/share/data"
      o: "addr=192.168.1.100,nfsvers=4,hard,intr"

远程挂载(SMB/CIFS)

volumes:
  smb_volume:
    driver: local
    driver_opts:
      type: cifs
      device: "//server/share"
      o: "username=user,password=pass,file_mode=0777,dir_mode=0777"

临时内存卷(tmpfs)

volumes:
  tmpfs_volume:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs
      o: "size=100m,uid=1000"

完整服务配置示例

version: '3.8'

# 自定义网络
networks:
  app-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.30.0.0/16
          gateway: 172.30.0.1

# 持久化卷
volumes:
  mysql-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./mysql-data

# 服务定义
services:
  # Web 服务
  nginx:
    image: nginx:alpine
    container_name: my-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./html:/usr/share/nginx/html
    networks:
      - app-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
    depends_on:
      - php

  # 数据库服务
  mysql:
    image: mysql:8.0
    container_name: my-mysql
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: app_db
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 1G
        reservations:
          cpus: "0.5"
          memory: 512M
    restart: on-failure:3

# 扩展字段(配置复用)
x-common-env: &common-env
  TZ: Asia/Shanghai
  LANG: en_US.UTF-8

常用服务配置参数速查

参数 说明 示例
image 镜像名称 nginx:alpine
container_name 容器名称(唯一) my-nginx
restart 重启策略 unless-stoppedalwayson-failure:3
ports 端口映射(宿主机:容器) - "80:80"
environment 环境变量 ENV_TEST: 123456
env_file 环境变量文件 - .env
volumes 挂载卷 - ./data:/app/data
networks 网络关联 - app-network
depends_on 启动依赖(服务顺序) - mysql
healthcheck 健康检查配置 test: ["CMD", "curl", "-f"]
command 覆盖默认命令 ["nginx", "-g", "daemon off;"]
entrypoint 覆盖默认入口点 ["/bin/sh", "-c"]
user 运行用户 root1000:1000

常用管理命令

操作 命令
启动所有服务 docker compose up -d
停止所有服务 docker compose stop
重启所有服务 docker compose restart
查看服务状态 docker compose ps
查看日志 docker compose logs -f --tail=100
重新构建并启动 docker compose up -d --build
停止并删除所有资源 docker compose down
停止并删除卷 docker compose down -v
执行单次命令 docker compose exec <service> <command>

常见问题与注意事项

版本兼容性

  • 3.x 版本支持 Swarm 模式,2.x 偏向单机使用
  • 推荐使用 3.8+ 版本,适配 Docker 20.10+,新格式 compose.yml 无需声明 version

端口映射注意事项

  • 映射已占用端口会导致容器启动失败
  • 映射 80:80 表示宿主机 80 端口 → 容器 80 端口
  • 多个服务不能映射同一个宿主机端口

数据持久化

  • 不使用卷挂载时,容器删除后数据会丢失
  • 使用 volumes 可在容器重建后保留数据

depends_on 的局限性

  • depends_on 仅控制启动顺序,不等待服务完全就绪
  • 如需等待服务就绪,需配合 healthcheck 或使用 wait-for-it 脚本

网络通信

  • 同一 Compose 项目中,服务默认互通,可通过服务名访问(如 http://mysql:3306
  • 使用自定义网络可更好控制网络隔离

参考链接