智能
助手
最大化  清空记录 停止  历史记录
翻译选中文本
选中一段文本后进行翻译
名词解释
选中一段文本后进行名词解释
知识图谱生成
通过图谱展示知识信息
登录用户在知识浏览页面可用
答案生成
AI自动回答一个问答功能中的问题
登录用户在问答浏览页面,且问题开放回答中可用
知识摘要
自动为当前知识生成摘要
知识浏览页面可用
知识问答
针对当前知识进行智能问答
知识浏览面可用
2025-12-23 22:31:53 版本 : 10. Docker Compose 简介与实践
作者: 文艺范儿 于 2025年12月23日 发布在分类 / Docker & K8S / docker进阶 下,并于 2025年12月23日 编辑
 历史版本

备注 修改日期 修改人
内容更新 2025-12-23 22:31:53[当前版本] 文艺范儿
创建版本 2025-12-23 22:30:05 文艺范儿

10. Docker Compose 简介与实践

10.1 什么是 Docker Compose

Docker Compose 是 Docker 官方提供的多容器编排工具,允许通过一个 YAML 文件(docker-compose.yml)定义一组相关联的服务、网络、存储卷,并使用一条命令完成创建、启动、停止等操作。

10.1.1 适用场景

  • 本地开发环境快速搭建(数据库 + Web + Cache)
  • CI/CD 流水线中集成测试环境
  • 小规模生产部署(替代 Swarm 的简单场景)
  • Kubernetes 前的过渡阶段(便于理解声明式服务模型)

10.1.2 设计原则(SRE视角)

  • 声明式优于命令式:配置即代码,可追溯、可版本控制
  • 幂等性:多次 apply 结果一致
  • 依赖管理与健康探测:确保服务启动顺序与可用性
  • 资源限制与隔离:通过 deploy.resourcesmem_limit预防资源争用
  • 可观测性内置:日志驱动、健康检查、Prometheus Exporter 集成

10.2 安装与版本差异

方式 说明 备注

二进制安装

下载 docker-compose-plugin(V2 插件形式)

Docker Desktop 已内置

包管理器

apt install docker-compose(V1 独立二进制)

逐步淘汰

V2 命令格式

docker compose(无短横线)

推荐,兼容 Plugin 架构

二进制安装

# 二进制下载命令
https://github.com/docker/compose/releases/download/v5.0.1/docker-compose-linux-aarch64

# 安装确认,这里安装docker的时候已经安装,没有安装的可以安装一下apt-get install -y docker-compose-plugin
[root@docker-71 ~]# docker compose version
Docker Compose version v5.0.0

10.3 核心概念与命令速查

10.3.1 核心概念

  • Service:一个容器实例的定义(镜像、端口、环境变量、依赖等)
  • Network:自定义网络,实现服务间 DNS 解析
  • Volume:持久化存储,独立于容器生命周期
  • Config / Secret:配置文件与密钥管理(V3.0+)

10.3.2 常用命令表

命令 作用 SRE 用途

docker compose up -d

后台启动所有服务

环境初始化

docker compose down

停止并删除容器、网络

环境销毁

docker compose ps

查看运行状态

健康检查

docker compose logs -f <svc>

实时日志

故障排查

docker compose exec <svc> sh

进入容器

调试

docker compose build

构建镜像

CI 流程

docker compose pull

拉取最新镜像

滚动更新

docker compose restart

重启服务

配置热加载

docker compose config

校验并输出合并后的配置

配置审计


10.4 docker-compose.yml 结构详解

10.4.1 基本结构框架

# 版本声明,新版本已经弃用
version: '3.8'

# 服务定义(核心部分)
services:
  service1:
    # 服务配置
  service2:
    # 服务配置

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

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

# 密钥定义(可选)
secrets:
  secret1:
    # 密钥配置

# 配置定义(可选)
configs:
  config1:
    # 配置配置

10.4.2 服务定义 (Services) - 核心部分

基本服务结构

services:
  web:                          # 服务名称(必填)
    image: nginx:alpine         # 使用的基础镜像(或使用 build)
    container_name: my-web      # 自定义容器名称
    hostname: web-server        # 容器主机名
    restart: unless-stopped     # 重启策略

    # 构建配置(与 image 二选一)
    build:
      context: ./app            # 构建上下文目录
      dockerfile: Dockerfile    # Dockerfile 文件名
      args:                     # 构建参数
        - NODE_VERSION=16
        - BUILD_DATE=2024-01-15

    # 端口映射
    ports:
      - "8080:80"               # 主机端口:容器端口
      - "8443:443"

    # 环境变量
    environment:                # 直接设置环境变量
      - TZ=Asia/Shanghai
      - DEBUG=false
    env_file:                   # 从文件加载环境变量
      - ./env/app.env
      - ./env/db.env

    # 命令行和入口点
    command: ["nginx", "-g", "daemon off;"]  # 覆盖默认命令
    entrypoint: ["/entrypoint.sh"]           # 覆盖入口点

    # 工作目录
    working_dir: /app

    # 用户和组
    user: "1000:1000"
    group_add:
      - "999"

    # 网络和链接
    networks:
      - frontend
      - backend
    links:                      # 链接到其他容器(已废弃,推荐用 networks)
      - db:database

    # 依赖关系
    depends_on:
      db:
        condition: service_healthy  # 依赖条件
        restart: true
      redis:
        condition: service_started

    # 数据卷挂载
    volumes:
      - ./app:/app:ro           # 绑定挂载(只读)
      - app_data:/app/data      # 命名卷
      - /tmp:/tmp:rw            # 匿名卷

    # 配置和密钥
    configs:
      - source: nginx_config
        target: /etc/nginx/nginx.conf
    secrets:
      - source: db_password
        target: /run/secrets/db_password
        uid: '1000'
        gid: '1000'
        mode: 0400

    # 资源限制
    deploy:                     # 主要用于 Docker Swarm
      resources:
        limits:
          cpus: '1.0'           # CPU 限制
          memory: 512M          # 内存限制
        reservations:
          cpus: '0.5'           # CPU 预留
          memory: 256M          # 内存预留

    # 健康检查
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s             # 检查间隔
      timeout: 10s              # 超时时间
      retries: 3                # 重试次数
      start_period: 40s         # 启动等待时间
      disable: false            # 是否禁用检查

    # 其他配置
    privileged: false          # 是否特权模式
    read_only: false           # 文件系统是否只读
    tmpfs:                     # 临时文件系统
      - /tmp
      - /var/run
    shm_size: 64M              # /dev/shm 大小
    stdin_open: false          # 是否保持 STDIN 打开
    tty: false                 # 是否分配伪终端
    sysctls:                   # 系统控制参数
      - net.core.somaxconn=1024

10.4.3 网络定义 (Networks)

networks:
  frontend:                    # 网络名称
    driver: bridge             # 网络驱动
    driver_opts:               # 驱动选项
      com.docker.network.bridge.name: frontend_net
    ipam:                      # IP 地址管理
      driver: default
      config:
        - subnet: 172.20.0.0/16    # 子网
          gateway: 172.20.0.1      # 网关
          ip_range: 172.20.240.0/20 # IP 范围
    external: false            # 是否为外部网络
    internal: false            # 是否为内部网络(禁止外网访问)
    attachable: false          # 是否允许独立容器连接
    enable_ipv6: false         # 是否启用 IPv6

  backend:
    driver: overlay            # Swarm 模式下的覆盖网络
    attachable: true

  external_network:            # 使用现有网络
    external: true
    name: my-existing-network  # 指定现有网络名称

10.4.4 数据卷定义 (Volumes)

volumes:
  mysql_data:                  # 命名卷
    driver: local              # 卷驱动
    driver_opts:               # 驱动选项
      type: none
      device: /custom/mysql/path
      o: bind
    external: false            # 是否为外部卷
    name: custom-mysql-data    # 自定义卷名称

  app_data:
    driver: nfs                # NFS 卷
    driver_opts:
      share: 192.168.1.100:/exports/app_data

  shared_volume:
    driver: local
    labels:                    # 元数据标签
      - "backup=daily"
      - "environment=production"

  # 匿名卷(在 services 中直接定义)
  # tmp_volume: ~

卷的类型和使用场景

类型 语法 用途 生命周期

绑定挂载

./host:/container

开发时使用源代码

随容器删除而保留

命名卷

volume_name:/container

生产环境数据持久化

独立于容器存在

匿名卷

/container/path

临时数据

容器删除时删除

10.4.5 密钥定义 (Secrets) - Docker Swarm 特性

secrets:
  db_password:                 # 密钥名称
    file: ./secrets/db_password.txt    # 从文件创建
    # 或从外部密钥管理系统创建
    external: true
    name: prod_db_password

  api_key:
    content: "your-api-key-here"       # 直接指定内容
    labels:
      - "environment=production"

在服务中使用:

services:
  app:
    secrets:
      - source: db_password           # 密钥源名称
        target: /run/secrets/db_pwd   # 容器中的目标路径
        uid: "1000"                   # 文件所有者
        gid: "1000"                   # 文件组
        mode: 0400                    # 文件权限

10.4.6 配置定义 (Configs) - Docker Swarm 特性

configs:
  nginx_config:
    file: ./config/nginx.conf         # 从文件创建配置
    template_driver: golang            # 模板驱动(支持变量替换)

  app_config:
    content: |
      server {
          listen 80;
          server_name localhost;
      }
    external: true
    name: global_app_config

在服务中使用:

services:
  nginx:
    configs:
      - source: nginx_config
        target: /etc/nginx/nginx.conf
        mode: 0444

10.4.7 高级特性

环境变量和变量替换:

# .env 文件
DB_HOST=localhost
DB_PORT=5432
APP_VERSION=1.0.0

# docker-compose.yml
services:
  app:
    image: myapp:${APP_VERSION}
    environment:
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
    ports:
      - "${HOST_PORT:-8080}:80"    # 默认值语法

扩展字段 (Extensions Fields):

# 定义可复用的配置片段
x-common-volumes: &common-volumes
  - /etc/localtime:/etc/localtime:ro
  - /var/run/docker.sock:/var/run/docker.sock

x-common-environment: &common-environment
  - TZ=Asia/Shanghai
  - LANG=C.UTF-8

services:
  web:
    volumes: *common-volumes
    environment: *common-environment
  worker:
    volumes: *common-volumes
    environment: *common-environment

多 Compose 文件组合:

# 基础配置
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

# docker-compose.base.yml
version: '3.8'
services:
  app:
    image: myapp:latest

# docker-compose.override.yml (开发环境)
services:
  app:
    volumes:
      - .:/app
    environment:
      - DEBUG=true

# docker-compose.prod.yml (生产环境)
services:
  app:
    environment:
      - DEBUG=false
    deploy:
      replicas: 3

构建参数和标签:

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - NODE_VERSION=16
        - BUILD_DATE
      cache_from:
        - node:16-alpine
      labels:
        - "maintainer=your-name"
        - "version=1.0"
      target: production        # 多阶段构建的目标阶段
    image: myapp:${BUILD_TAG:-latest}
    labels:                    # 容器标签
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.example.com`)"

10.5 案例:Docker Compose 安装 Zabbix 完整案例

10.5.1 架构设计与说明

组件角色

  • Zabbix Server:监控服务端,负责收集和处理监控数据
  • MySQL:Zabbix 后端数据库,存储配置和历史数据
  • Zabbix java gateway:让 Zabbix 能够监控 Java 应用程序
  • Zabbix Web:PHP 应用程序,通过 Nginx 提供服务

10.5.2 目录结构设计

zabbix-docker/
├── docker-compose.yml
├── .env

10.5.3 环境配置文件

.env 文件(敏感信息管理)
mkdir zabbix-docker
cd zabbix-docker
# 创建 .env 文件,这里可以定义更多变量,如版本号 用户名 密码等 这里只做示例
cat > .env << 'EOF'
# 时区
TZ=Asia/Shanghai
EOF

10.5.4 Docker Compose 主配置文件

注意:缩进很关键,有一行缩进不合适会导致报错:yaml: line 1: did not find expected key

cat docker-compose.yml

services:
  # MySQL 数据库
  mysql:
    image: mysql:8.3.0-oracle            # 使用 MySQL 8.3 官方镜像
    container_name: zabbix-mysql         # 容器名称为 zabbix-mysql
    restart: unless-stopped                # 除非手动停止,否则总是重启
    environment:                        # 表示从 .env文件或系统环境变量中读取值
      MYSQL_ROOT_PASSWORD: Qwer1234        # root 密码
      MYSQL_DATABASE: zabbix            # 自动创建的数据库名
      MYSQL_USER: zabbix                # 自动创建的用户名
      MYSQL_PASSWORD: 123456            # 用户密码
      TZ: ${TZ}                            # 设置时区为中国上海,此处调用.env的变量
    volumes:
      - mysql_data:/var/lib/mysql        # 将 MySQL 数据目录挂载到命名卷 mysql_data
    networks:
      - zabbix-net                        # 加入名为 zabbix-net 的网络
    command: 
      --character-set-server=utf8mb4 
      --collation-server=utf8mb4_bin
      --default-authentication-plugin=mysql_native_password        # 使用传统密码认证插件
    healthcheck:                                                # 使用健康检查
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$(cat $$MYSQL_PASSWORD_FILE)"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          cpus: 2.0                    # 限制最多使用 2 个 CPU 核心
          memory: 2g                # 限制最多使用 2GB 内存

  # Zabbix java gateway
  zabbix-java-gateway:
    container_name: zabbix-java-gateway
    image: zabbix/zabbix-java-gateway:alpine-6.4-latest
    restart: unless-stopped
    ports:
      - "10052:10052"
    networks:
       - zabbix-net
    healthcheck:
      test: ["CMD", "sh", "-c", "ps aux | grep abbix-java-gateway | grep -v grep"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: 1.0
          memory: 1g

  # Zabbix Server
  zabbix-server:
    image: zabbix/zabbix-server-mysql:alpine-6.4-latest
    container_name: zabbix-server
    restart: unless-stopped
    environment:
      DB_SERVER_HOST: mysql
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_ROOT_PASSWORD: Qwer1234
      MYSQL_PASSWORD: 123456
      ZBX_JAVAGATEWAY: zabbix-java-gateway
      TZ: ${TZ}
      ZBX_DEBUGLEVEL: 3
    ports:
      - "10051:10051"                    # 映射端口
    depends_on:                            # 定义服务依赖关系
      mysql:                            # 依赖的服务名称
        condition: service_healthy        # 只有当 mysql 服务处于健康状态时,才启动当前服务
    volumes:
      - zabbix_server_data:/var/lib/zabbix
      - zabbix_server_alertscripts:/usr/lib/zabbix/alertscripts
      - zabbix_server_externalscripts:/usr/lib/zabbix/externalscripts
    networks:
      - zabbix-net
    healthcheck:
      test: ["CMD", "sh", "-c", "ps aux | grep zabbix_server | grep -v grep"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: 1.0
          memory: 1g

  # Zabbix Web 界面
  zabbix-web:
    image: zabbix/zabbix-web-nginx-mysql:alpine-6.4-latest
    container_name: zabbix-web
    restart: unless-stopped
    ports:
      - "80:8080"
    environment:
      ZBX_SERVER_HOST: zabbix-server
      DB_SERVER_HOST: mysql
      MYSQL_DATABASE: zabbix
      MYSQL_USER: zabbix
      MYSQL_ROOT_PASSWORD: Qwer1234
      MYSQL_PASSWORD: 123456
      PHP_TZ: ${TZ}
      ZBX_SERVER_NAME: "Zabbix-Docker-Monitor"
    depends_on:
      zabbix-server:
        condition: service_healthy
      mysql:
        condition: service_healthy
    networks:
      - zabbix-net
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/"]
      interval: 30s
      timeout: 10s
      retries: 3


# 网络定义
networks:
  zabbix-net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.100.0/24
          gateway: 172.20.100.254

# 数据卷
volumes:
  mysql_data:
    driver: local    # local指的是 本地卷驱动程序(Local Volume Driver),它是 Docker 的默认卷驱动,用于在 Docker 主机的本地文件系统上创建和管理数据卷
  zabbix_server_data:
    driver: local
  zabbix_server_alertscripts:
    driver: local
  zabbix_server_externalscripts:
    driver: local

10.5.5 启动服务

# 启动服务 注意:要在docker-compose的目录中执行
docker compose up -d

# 检查服务状态
docker compose ps

# === 部署完成 ==="
# Zabbix Web 界面访问地址: http://IP:80
# 默认登录账号: Admin
# 默认密码: zabbix

# 查看日志: docker compose logs -f
# 停止并移除容器、网络、镜像等: docker compose down
# 停止并删除容器、网络,同时删除关联的命名卷 docker compose down -v
历史版本-目录  [回到顶端]
    文艺知识分享平台 -V 5.2.5 -wcp