Docker Compose详解

715 阅读16分钟

一,介绍

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具,它通过一个简单的 YAML 文件(docker-compose.yml)来配置应用的各个服务、网络和存储卷,从而简化多容器应用的部署和管理。

核心概念

  • 服务(Service): 每个服务对应一个容器,定义容器的镜像、端口映射、环境变量、依赖关系等。例如,一个 Web 应用可能包含 web 服务(前端)和 db 服务(数据库)。
  • 项目(Project): 由一组关联的服务组成,默认以当前目录名作为项目名(可通过 -p 参数指定)。所有容器名称会以 项目名_服务名_序号 的格式生成。
  • YAML 文件docker-compose.yml 是核心配置文件,定义了服务、网络、卷等资源。支持版本化配置(如 version: "3.9")。

主要功能

  • 一键启动/停止所有服务: 通过 docker compose updocker compose down 命令管理整个应用的生命周期。
  • 环境变量支持: 支持从 .env 文件或命令行注入环境变量,便于配置管理(如数据库密码)。
  • 服务依赖管理: 通过 depends_on 定义服务启动顺序。
  • 扩展服务实例: 使用 docker compose up --scale service=num 快速扩展容器实例数量。
  • 本地开发友好: 支持绑定本地代码目录到容器,实现实时重载(无需重新构建镜像)。

二,安装Docker Compose

# 下载 Docker Compose V2(集成到 Docker CLI),这个是Ubuntu系统的才能用apt
sudo apt-get install docker-compose-plugin
# 验证安装
docker compose version


# 安装 Docker Compose V2(作为 Docker 插件),这个是CentOs系统的才能用yum
sudo yum install docker-compose-plugin

# 验证安装
docker compose version

三,使用示例

  1. 创建 docker-compose.yml

    version: "3.9"
    services:
      web:
        image: nginx:alpine
        ports:
          - "80:80"
    
  2. 启动服务:

    docker compose up -d
    
  3. 查看运行状态:

    docker compose ps
    

四,核心操作命令

4.1 生命周期管理

docker compose up

  • 作用:根据 docker-compose.yml 启动所有服务(前台运行)。

  • 默认行为

    • 构建缺失的镜像。
    • 创建网络和存储卷。
    • depends_on 顺序启动容器。
    • 实时输出所有容器的日志到终端。
  • 示例

    # 启动所有服务(前台运行)
    docker compose up
    
    # 仅启动 web 和 redis 服务
    docker compose up web redis
    
  • 适用场景

    • 开发调试:实时查看日志,快速定位问题。
    • 服务依赖验证:观察服务启动顺序是否正确。
  • 注意事项

    • Ctrl+C 终止命令时,默认会停止并删除容器(除非使用 -d)。

docker compose up -d

  • 作用后台启动服务(Detached Mode)。

  • 核心参数

    • -d--detach:后台运行。
    • --build:强制重新构建镜像。
    • --scale <service>=<num>:扩展服务实例数量。
  • 示例

    # 后台启动所有服务
    docker compose up -d
    
    # 重新构建镜像并启动
    docker compose up -d --build
    
    # 启动 3 个 web 实例
    docker compose up -d --scale web=3
    
  • 使用场景

    • 生产环境部署:服务长期运行。
    • 多实例扩展:负载均衡或性能测试。
  • 注意事项

    • 使用 --scale 时,确保端口不冲突(如动态端口映射)。

docker compose down

  • 作用:停止并删除所有容器、网络,默认保留存储卷

  • 常用选项

    • -v--volumes:同时删除存储卷。
    • --rmi all:删除所有相关镜像。
  • 示例

    # 删除容器和网络(保留卷)
    docker compose down
    
    # 彻底清理所有资源(容器、网络、卷)
    docker compose down -v --rmi all
    
  • 适用场景

    • 环境清理:测试完成后释放资源。
    • 配置重置:重新部署前确保干净状态。
  • 注意事项

    • 使用 -v 会永久删除卷数据,慎用!

docker compose stop

  • 作用停止运行中的容器,但不删除容器或资源(网络、卷保留)。

  • 行为

    • 容器状态变为 Exited
    • 可通过 docker compose start 重新启动。
  • 示例

    # 停止所有服务
    docker compose stop
    
    # 仅停止 web 服务
    docker compose stop web
    
  • 适用场景

    • 临时释放资源:暂停服务但不删除配置。
    • 调试冻结状态:保留容器现场供后续检查。

docker compose start

  • 作用重新启动已停止的容器(基于现有配置)。

  • 限制:无法修改配置(如需更新配置,需先运行 docker compose up)。

  • 示例

    # 启动所有已停止的服务
    docker compose start
    
    # 仅启动 redis 服务
    docker compose start redis
    
  • 适用场景

    • 快速恢复服务:无需重新构建或创建资源。
    • 短时维护后重启:如主机资源调整。

docker compose restart

  • 作用重启容器(先停止再启动)。

  • 行为

    • 保持原有配置和资源。
    • 适用于容器内部状态异常或配置热更新失败。
  • 示例:

    # 重启所有服务
    docker compose restart
    
    # 仅重启 web 服务
    docker compose restart web
    
  • 适用场景

    • 应用配置更新:如修改了环境变量但无需重建镜像。
    • 服务异常恢复:如进程崩溃但容器仍运行。

4.2 查看状态与日志

docker compose ps

功能

  • 列出当前项目下所有容器的基本信息,包括 容器名称、服务名、状态、端口映射 等。
  • 仅显示运行中的容器(类似 docker ps,但按项目过滤)。

示例

# 查看所有服务的容器状态
docker compose ps

# 仅查看 web 服务的容器状态
docker compose ps web

输出示例

NAME                COMMAND                  SERVICE             STATUS              PORTS
myapp-web-1         "nginx -g 'daemon of…"   web                 running             0.0.0.0:80->80/tcp
myapp-db-1          "docker-entrypoint.s…"   db                  running             5432/tcp

关键字段解析

字段说明
NAME容器名称(格式:项目名_服务名_序号,如 myapp-web-1)。
SERVICE服务名称(对应 docker-compose.yml 中的定义)。
STATUS容器状态(如 runningexitedrestarting)。
PORTS端口映射(格式:主机端口->容器端口)。

适用场景

  • 快速确认服务是否正常启动。
  • 检查端口映射是否正确生效。

docker compose logs

功能

  • 显示 所有服务 的日志输出(默认从容器启动开始的历史日志)。
  • 支持实时跟踪日志流(类似 tail -f)。

常用选项

选项说明
-f / --follow持续输出实时日志(按 Ctrl+C 退出)。
--tail <行数>仅显示最后 N 行日志(如 --tail 100)。
--timestamps显示日志时间戳。
--no-color禁用彩色输出。

示例

# 查看所有服务的日志
docker compose logs

# 实时跟踪所有服务的日志
docker compose logs -f

# 查看 web 服务的最后 50 行日志
docker compose logs --tail 50 web

# 显示带时间戳的日志
docker compose logs --timestamps

适用场景

  • 调试服务启动失败问题。
  • 监控服务运行时的实时行为(如 API 请求处理)。

docker compose logs <service>

功能

  • 仅显示 特定服务 的日志,其他服务日志被过滤。
  • 支持相同的日志选项(-f--tail 等)。

示例

# 实时跟踪 web 服务的日志
docker compose logs -f web

# 查看 db 服务的最后 20 行日志
docker compose logs --tail 20 db

适用场景

  • 精准定位单个服务的异常行为。
  • 避免多服务日志混杂导致信息过载。

docker compose top

功能

  • 显示容器内 正在运行的进程列表(类似 Linux 的 top 命令)。
  • 查看进程的 PID、用户、CPU/内存占用 等信息。

示例

# 查看所有容器的进程
docker compose top

# 查看 web 服务的进程
docker compose top web

输出示例

myapp-web-1
UID    PID    PPID   C   STIME   TTY   TIME      CMD
root   1234   1228   0   14:30   ?     00:00:01  nginx: master process
root   1235   1234   0   14:30   ?     00:00:00  nginx: worker process

myapp-db-1
UID    PID    PPID   C   STIME   TTY   TIME      CMD
postgres 2345 2339   0   14:30   ?     00:00:03  postgres

关键字段解析

字段说明
UID进程运行的用户 ID。
PID进程 ID(容器内的 PID)。
CMD进程启动命令。

适用场景

  • 分析容器内进程资源占用(如 CPU、内存泄漏)。
  • 确认服务是否正确启动预期进程(如 Nginx 的 Master/Worker 进程)。

4.3 服务操作

docker compose build

功能

  • 根据 docker-compose.yml 中服务的 build 配置,构建或重新构建镜像
  • 支持指定服务名,仅构建特定服务的镜像。

常用选项

选项说明
--no-cache忽略构建缓存,强制全新构建。
--pull构建时拉取基础镜像的最新版本。
--progress <type>设置构建进度输出类型(auto, plain, tty)。

示例

# 构建所有服务的镜像
docker compose build

# 强制重新构建 web 服务镜像(不使用缓存)
docker compose build --no-cache web

# 构建时拉取最新基础镜像
docker compose build --pull

适用场景

  • 开发环境:修改 Dockerfile 后需重新构建镜像。
  • CI/CD 流水线:自动化构建镜像并推送到仓库。
  • 依赖更新:确保基础镜像为最新版本(如 FROM node:20 更新后)。

注意事项

  • 若服务配置了 image 字段,构建后的镜像会以该名称标记。

docker compose pull

功能

  • 从镜像仓库(如 Docker Hub)拉取服务定义的镜像
  • 适用于使用预构建镜像(而非本地构建)的服务。

常用选项

选项说明
--ignore-pull-failures忽略拉取失败的镜像,继续其他操作。

示例

# 拉取所有服务的镜像
docker compose pull

# 仅拉取 redis 服务的镜像
docker compose pull redis

适用场景

  • 部署准备:确保所有镜像在本地可用,避免运行时下载延迟。
  • 镜像更新:获取远程仓库中的最新版本镜像(需配合 docker compose up 重启服务)。

注意事项

  • 若服务配置了 build 而非 imagepull 不会生效。

docker compose exec <service> <command>

功能

  • 在已运行的容器内执行指定命令,适合调试或执行临时任务。
  • 容器必须处于运行状态(STATUSrunning)。

语法

docker compose exec [选项] <服务名> <命令>

常用选项

选项说明
-d后台运行命令(不占用终端)。
-it启用交互式终端(常用于执行 Shell)。
--env KEY=VALUE向容器注入环境变量。
--user以指定用户身份执行命令(如 --user root)。

示例

# 进入 web 容器的 Shell(交互式终端)
docker compose exec -it web sh

# 查看数据库容器的日志文件
docker compose exec db tail -f /var/log/postgresql.log

# 后台执行耗时任务
docker compose exec -d web python batch_job.py

适用场景

  • 调试容器:检查文件、进程或网络状态。
  • 执行维护任务:如数据库备份、日志清理。
  • 注入临时配置:修改运行中的服务参数。

注意事项

  • 命令执行完毕后,容器仍保持运行状态。

docker compose run <service> <command>

功能

  • 启动一个新容器并执行指定命令,完成后容器自动停止。
  • 不依赖 depends_on:即使其他服务未启动,也可单独运行。
  • 支持覆盖配置(如环境变量、端口映射)。

语法

docker compose run [选项] <服务名> <命令>

常用选项

选项说明
--rm命令执行后自动删除容器。
-e KEY=VALUE覆盖环境变量(优先级高于 environment 配置)。
-p 主机端口:容器端口覆盖端口映射。
--no-deps不启动依赖服务。
-v 主机目录:容器目录添加临时卷挂载。

示例

# 执行数据库迁移脚本(完成后删除容器)
docker compose run --rm web python manage.py migrate

# 启动临时测试容器(指定环境变量)
docker compose run -e DEBUG=1 web npm test

# 挂载本地目录并运行命令
docker compose run -v ./config:/app/config web bash

适用场景

  • 一次性任务:如数据库迁移、单元测试。
  • 调试隔离环境:独立于其他服务运行特定命令。
  • 覆盖配置测试:临时修改环境变量或卷挂载。

注意事项

  • 默认不会自动删除容器(需手动添加 --rm)。
  • 新容器与项目网络连接,可访问其他服务(除非使用 --no-deps)。

4.4 扩展与配置

docker compose up --scale <service>=<num>

功能

  • 动态调整指定服务的容器实例数量,实现横向扩展。
  • 适用于无状态服务(如 Web 服务器),需结合负载均衡器使用。

语法

docker compose up -d --scale <服务名>=<实例数量>

示例

# 启动 3 个 web 服务实例
docker compose up -d --scale web=3

输出示例

[+] Running 4/4
 ✔ Network myapp_default      Created
 ✔ Container myapp-db-1      Running
 ✔ Container myapp-web-1     Running
 ✔ Container myapp-web-2     Running
 ✔ Container myapp-web-3     Running

适用场景

  • 负载均衡:通过多个实例分摊流量压力。
  • 容错测试:模拟实例故障并验证服务恢复能力。

注意事项

  • 端口冲突:若服务配置了固定端口(如 "80:80"),扩展时将因端口占用失败。 解决方案: 改用动态端口映射(仅暴露容器端口)或使用负载均衡器(如 Nginx):

    ports:
      - "8080-8085:80"  # 主机端口范围映射到容器 80 端口
    
  • 数据一致性:确保服务无状态,避免依赖本地存储。

docker compose config

功能

  • 验证 docker-compose.yml 语法,检测配置错误(如无效属性、缩进错误)。
  • 输出合并后的完整配置(包括环境变量和扩展文件)。

语法

docker compose config [选项]

常用选项

选项说明
--services仅显示服务名称。
--volumes仅显示存储卷配置。
--hash="<服务名>"生成指定服务的配置哈希(用于版本控制)。

示例

# 验证配置并输出最终配置
docker compose config

# 仅显示服务名称
docker compose config --services
# 输出:web db

# 生成 web 服务的配置哈希
docker compose config --hash="web"
# 输出:sha256:7d4c5a6b3e8d...

适用场景

  • 调试配置:快速定位 YAML 语法错误或逻辑问题。
  • 审计配置:查看环境变量替换后的实际生效配置。
  • CI/CD 集成:自动化检查 Compose 文件的合法性。

注意事项

  • 若配置引用了未定义的环境变量,会直接报错(如 ${DB_PASSWORD} 未在 .env 中定义)。

docker compose -f <file1.yml> -f <file2.yml> up

功能

  • 通过多个 Compose 文件组合配置,后者覆盖前者同名配置。
  • 支持不同环境(开发、测试、生产)的差异化配置管理。

语法

docker compose -f <主文件.yml> -f <覆盖文件.yml> up [选项]

示例

# 合并基础文件和生产环境覆盖文件
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

文件示例

  • 基础文件 docker-compose.yml

    version: "3.9"
    services:
      web:
        image: myapp:latest
        ports:
          - "3000:3000"
      db:
        image: postgres:13
    
  • 生产环境覆盖文件 docker-compose.prod.yml

    services:
      web:
        ports:
          - "80:3000"  # 覆盖端口
        environment:
          NODE_ENV: production
      db:
        environment:
          POSTGRES_PASSWORD: ${DB_PASSWORD}
    

合并后等效配置

version: "3.9"
services:
  web:
    image: myapp:latest
    ports:
      - "80:3000"
    environment:
      NODE_ENV: production
  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}

适用场景

  • 多环境管理:通过不同文件适配开发、测试、生产环境。
  • 模块化配置:将通用配置与特性配置分离(如日志、监控)。
  • 团队协作:共享基础配置,个人通过本地文件覆盖调试参数。

注意事项

  • 优先级规则:后面文件的配置覆盖前面文件的同名配置。
  • 版本兼容性:所有文件需使用相同的 Compose 版本。

五,docker-compose.yml 配置文件详解

docker-compose.yml 是 Docker Compose 的核心配置文件,用于定义多容器应用的服务、网络、存储卷等资源。

5.1 文件结构

5.1.1 版本声明(version

version: "3.9"  # 指定 Compose 文件格式版本
  • 作用:定义 Compose 文件语法版本,不同版本支持的功能不同。
  • 推荐版本
    • 最新稳定版为 3.9(需 Docker Engine ≥ 19.03)。
    • 完整版本支持列表:Docker 官方文档

5.1.2 服务定义(services

services:  # 定义所有容器服务
  web:     # 服务名称(自定义)
    image: nginx:alpine  # 使用镜像
    ports:
      - "80:80"
  
  db:
    build: ./db  # 通过 Dockerfile 构建镜像
  • 每个服务对应一个容器,可定义镜像、端口、环境变量等。
  • 服务名称:自定义名称,用于命令操作(如 docker compose up web)。

5.1.3 存储卷(volumes

volumes:  # 定义持久化存储卷
  db_data:  # 卷名称(自定义)
  • 作用:持久化容器数据(如数据库文件)。
  • 默认行为
    • 未显式定义时,Compose 自动创建匿名卷。
    • 显式定义卷可跨容器复用(如多个服务共享数据)。

5.1.4 网络(networks

networks:  # 定义自定义网络
  app_net:
    driver: bridge  # 网络驱动(默认 bridge)
  • 作用:隔离服务间通信,提升安全性。
  • 默认行为
    • 所有服务默认加入名为 项目名_default 的 bridge 网络。
    • 自定义网络可实现更精细的控制(如指定子网、IP 地址)。

5.2 常用配置项

5.2.1 镜像与构建(imagebuild

  • 直接使用镜像

    web:
      image: nginx:alpine  # 从仓库拉取镜像
    
  • 通过 Dockerfile 构建镜像

    web:
      build:
        context: .         # 构建上下文路径
        dockerfile: Dockerfile.dev  # 指定 Dockerfile 文件名
        args:              # 构建参数
          NODE_ENV: development
    

5.2.2 端口映射(ports

ports:
  - "80:80"            # 短语法:主机端口:容器端口
  - target: 80         # 长语法(支持高级配置)
    published: 8080
    protocol: tcp
    mode: host         # 主机模式(直接暴露主机网络)
  • 动态端口映射:仅暴露容器端口(如 "3000"),主机端口随机分配。

5.2.3 卷挂载(volumes

volumes:
  - ./data:/app/data          # 绑定挂载(主机目录 → 容器)
  - config_volume:/app/config # 命名卷挂载
  • 绑定挂载:直接映射主机目录(适合开发环境实时同步代码)。
  • 命名卷:由 Docker 管理(适合生产环境持久化数据)。

5.2.4 环境变量(environmentenv_file

environment:
  - DEBUG=1             # 直接定义变量
  - DB_HOST=db

env_file:
  - .env                # 从文件加载变量
  - .env.override       # 后者覆盖前者同名变量
  • 变量优先级:命令行 > .env 文件 > environment 配置。

5.2.5 依赖管理(depends_on

depends_on:
  - db                  # 简单依赖(按顺序启动)
  - redis:
      condition: service_healthy  # 等待依赖服务健康
  • 健康检查配置示例

    db:
      healthcheck:
        test: ["CMD", "pg_isready", "-U", "postgres"]
        interval: 10s
        timeout: 5s
        retries: 3
    

5.2.6 资源限制(deploy

deploy:
  resources:
    limits:
      cpus: "0.5"      # 限制 CPU 使用率
      memory: 512M     # 限制内存
  • 注意deploy 配置仅在 Swarm 模式下生效。

5.2.7 重启策略(restart

restart: unless-stopped  # 自动重启(除非手动停止)
  • 可选值no(默认)、alwayson-failureunless-stopped

5.3 网络与卷高级配置

5.3.1 自定义网络

networks:
  backend:
    driver: bridge
    ipam:                  # IP 地址管理
      config:
        - subnet: 172.20.0.0/24
          gateway: 172.20.0.1

services:
  web:
    networks:
      backend:
        ipv4_address: 172.20.0.10  # 固定 IP

5.3.2 卷驱动选项

volumes:
  db_data:
    driver: local
    driver_opts:
      type: nfs          # 使用 NFS 驱动
      o: addr=192.168.1.1,rw
      device: ":/path/to/nfs"

5.4 完整示例

version: "3.9"

services:
  web:
    build: .
    ports:
      - "80:8000"
    volumes:
      - ./app:/app
    environment:
      - DEBUG=1
    depends_on:
      - db
      - redis

  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: example
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:alpine
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes

volumes:
  postgres_data:
  redis_data:

networks:
  default:
    driver: bridge

六,典型使用场景

场景 1:本地开发环境

version: "3.9"
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app  # 实时同步代码
    depends_on:
      - redis

  redis:
    image: redis:alpine
    volumes:
      - redis_data:/data

volumes:
  redis_data:
  • 运行:docker compose up -d
  • 修改代码后,容器自动加载新内容(无需重启)。

场景 2:多服务扩展

# 启动 3 个 Web 实例和 1 个 Redis
docker compose up -d --scale web=3
  • 适用于负载测试或横向扩展。

场景 3:多环境配置

  1. 创建基础文件 docker-compose.yml

    version: "3.9"
    services:
      app:
        image: myapp
        env_file:
          - .env
    
  2. 创建开发环境覆盖文件 docker-compose.override.yml

    services:
      app:
        ports:
          - "8080:80"
        volumes:
          - ./src:/app/src
    
  3. 运行:docker compose up 会自动合并文件。

七,高级功能

7.1 服务依赖与启动顺序

services:
  web:
    depends_on:
      db:
        condition: service_healthy  # 等待 db 健康后再启动

  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]

7.2 配置共享与扩展

# docker-compose.prod.yml
services:
  web:
    ports:
      - "80:80"
    environment:
      NODE_ENV: production
  • 运行生产配置:docker compose -f docker-compose.yml -f docker-compose.prod.yml up

7.3 资源限制

services:
  redis:
    image: redis
    deploy:  # 仅在使用 Swarm 模式时有效
      resources:
        limits:
          cpus: "0.5"
          memory: 512M