目录

一、核心定位与价值

二、核心组件与工作原理

1. 配置文件(compose.yml)

2. Compose 命令行工具(docker-compose)

3. Docker 引擎

三、compose.yml配置文件详解

1. 版本声明(version)

2. 服务定义(services)

3. 网络配置(networks)

4. 数据卷配置(volumes)

四、常用命令(docker compose)

五、高级特性与最佳实践

1. 多环境配置(使用多个 YAML 文件)

2. 环境变量替换(.env文件)

3. 容器间通信

4. 依赖管理注意事项

5. 生产环境使用建议

六、常见问题与排查

1. 配置文件语法错误

2. 容器启动后立即退出

3. 容器间无法通信

4. 数据卷挂载失败

总结


Docker Compose 是 Docker 官方推出的用于定义和运行多容器 Docker 应用的工具,通过单一配置文件(compose.yml)声明应用所需的所有服务,再通过一条命令即可创建并启动所有服务,极大简化了多容器应用的部署与管理流程。

一、核心定位与价值

在实际开发中,大多数应用并非单容器运行(如一个 Web 应用可能需要 Web 服务、数据库、缓存、消息队列等多个容器协同工作)。手动管理这些容器的启动顺序、网络连接、数据卷挂载等操作会非常繁琐,而 Docker Compose 的核心价值在于:

  • 简化配置:用一个 YAML 文件(compose.yml)集中定义所有容器的配置(镜像、端口、环境变量、依赖关系等);
  • 统一管理:通过单一命令(如docker-compose up)创建、启动、停止所有服务,避免逐个操作容器;
  • 环境一致:确保开发、测试、生产环境的配置一致,解决 “在我电脑上能运行” 的问题;
  • 依赖协调:自动处理容器间的启动顺序和网络连接(如先启动数据库,再启动依赖它的应用)。

二、核心组件与工作原理

Docker Compose 的工作依赖三个核心部分,三者协同实现多容器应用的生命周期管理:

1. 配置文件(compose.yml)

这是 Compose 的 “灵魂”,采用 YAML 格式,用于声明应用的所有服务(容器)、网络、数据卷等资源。文件名默认是compose.yml(或docker-compose.yml,两者等效),也可通过-f参数指定自定义文件名(如docker-compose.prod.yml)。


2. Compose 命令行工具(docker-compose)

用于解析配置文件并与 Docker 引擎交互,执行创建、启动、停止、删除等操作。工具已集成到 Docker CLI(Docker 20.10 + 版本),可直接通过docker compose命令使用(旧版本需单独安装docker-compose)。


3. Docker 引擎

作为底层支撑,负责实际创建容器、网络、数据卷等资源,并按照配置文件的定义协调容器运行。

工作流程

· 开发者编写compose.yml,定义所有服务(如web、db、redis)及依赖关系;

· 执行docker compose up,Compose 工具解析配置文件,调用 Docker 引擎 API;

· Docker 引擎按顺序创建网络、数据卷,再根据配置启动所有服务容器;

· 容器间通过 Compose 自动创建的网络通信,数据通过声明的数据卷持久化;

· 执行docker compose down,Compose 工具通知 Docker 引擎停止并删除容器、网络(数据卷默认保留)。

三、compose.yml配置文件详解

compose.yml是 Compose 的核心,其结构清晰,主要包含version、services、networks、volumes四个顶层配置项(其中services为必填项)。

1. 版本声明(version)

指定 Compose 文件格式的版本,需与 Docker 引擎版本兼容(推荐使用3.x,适配 Docker 17.06+)。例如:

version: '3.8'  # 最常用的稳定版本,支持大部分新特性

注意:Docker 20.10 + 版本已弱化version字段,若省略则默认使用最新版本格式。


2. 服务定义(services)

services是配置文件的核心,用于定义应用所需的各个容器(每个服务对应一个容器或一组容器)。每个服务下可配置多种属性,常用属性如下:

属性

作用

示例

image

指定容器使用的镜像(若本地没有则自动拉取)

image: nginx:1.23

build

从本地 Dockerfile 构建镜像(替代image)

build: ./webapp(指定 Dockerfile 目录)

ports

端口映射(宿主机端口:容器端口),与docker run -p一致

ports: - "8080:80"

environment

设置环境变量(键值对或列表形式),与docker run -e一致

environment: - DB_HOST=db - DB_PORT=3306

env_file

从文件加载环境变量(替代environment,适合变量较多的场景)

env_file: ./.env

volumes

挂载数据卷(持久化数据),格式:[卷名:容器路径]或[宿主机路径:容器路径]

volumes: - mysql-data:/var/lib/mysql

networks

指定服务加入的网络(需在networks中定义)

networks: - app-network

depends_on

声明服务依赖关系(控制启动顺序,如web依赖db,则先启动db)

depends_on: - db - redis

restart

容器重启策略(如always表示总是重启)

restart: always

command

覆盖容器默认启动命令(与docker run后的命令作用一致)

command: python app.py --debug

container_name

指定容器名称(默认自动生成,如project_web_1)

container_name: my-web

示例服务配置

services:
  # Web服务(基于本地Dockerfile构建)
  web:
    build: ./web  # Dockerfile所在目录
    ports:
      - "80:80"   # 宿主机80端口映射到容器80端口
    environment:
      - FLASK_ENV=production
      - DB_URL=mysql://user:pass@db:3306/mydb  # 直接通过服务名db访问数据库
    depends_on:
      - db        # 依赖db服务,db启动后再启动web
    networks:
      - app-net   # 加入app-net网络

  # 数据库服务(使用官方MySQL镜像)
  db:
    image: mysql:8.0
    volumes:
      - mysql-data:/var/lib/mysql  # 挂载数据卷,持久化MySQL数据
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=mydb
    networks:
      - app-net   # 与web在同一网络,可通过服务名通信

  # 缓存服务(使用Redis)
  redis:
    image: redis:alpine
    networks:
      - app-net

3. 网络配置(networks)

定义服务间通信的网络,默认情况下 Compose 会自动创建一个名为项目名_default的桥接网络(所有服务默认加入此网络),但也可自定义网络以实现更灵活的隔离。

常用配置:

  • driver:指定网络驱动(默认bridge,还支持overlay、macvlan等);
  • ipam:自定义 IP 网段(避免与其他网络冲突)。

示例网络配置

networks:
  app-net:  # 自定义网络名称
    driver: bridge  # 使用桥接驱动
    ipam:
      config:
        - subnet: 192.168.10.0/24  # 自定义IP网段
          gateway: 192.168.10.1    # 网关地址

4. 数据卷配置(volumes)

定义数据卷(用于持久化容器数据,避免容器删除后数据丢失),Compose 会自动创建声明的卷,并在服务间共享。

常用配置:

  • driver:卷驱动(默认local,本地存储;还支持nfs、glusterfs等分布式存储);
  • driver_opts:驱动选项(如指定 NFS 服务器地址)。

示例数据卷配置

volumes:
  mysql-data:  # 卷名称,服务中通过此名称引用
    driver: local  # 本地存储
    driver_opts:
      type: 'none'
      device: '/opt/mysql/data'  # 绑定宿主机/opt/mysql/data目录
      o: 'bind'

四、常用命令(docker compose)

Docker Compose 的命令简洁直观,通过docker compose <命令>即可管理应用生命周期,常用命令如下:

命令

作用

常用选项

up

创建并启动所有服务(若镜像不存在则构建 / 拉取)

-d:后台运行;--build:强制构建镜像

down

停止并删除所有服务容器、网络(数据卷默认保留)

-v:同时删除数据卷;--rmi all:删除关联镜像

start

启动已创建的服务容器

-

stop

停止运行中的服务容器(不删除)

-

restart

重启服务容器

-

ps

查看服务容器的状态(运行中、停止等)

-a:显示所有容器(包括停止的)

logs

查看服务容器的日志(实时输出)

-f:实时跟踪日志;--tail 100:显示最后 100 行

exec

进入运行中的容器执行命令(类似docker exec)

docker compose exec web bash:进入 web 容器的 bash

build

构建服务的镜像(仅适用于build定义的服务)

--no-cache:不使用缓存构建

pull

拉取服务所需的镜像(仅适用于image定义的服务)

-

config

验证配置文件语法是否正确

--quiet:仅输出错误信息

示例操作流程

# 1. 基于compose.yml启动服务(后台运行,强制构建镜像)
docker compose up -d --build

# 2. 查看服务状态
docker compose ps

# 3. 查看web服务的实时日志
docker compose logs -f web

# 4. 进入db容器执行命令(如登录MySQL)
docker compose exec db mysql -u root -p

# 5. 停止服务(保留容器、网络、数据卷)
docker compose stop

# 6. 重启服务
docker compose restart

# 7. 停止并删除所有容器、网络(保留数据卷)
docker compose down

# 8. 停止并删除所有容器、网络、数据卷
docker compose down -v

五、高级特性与最佳实践

1. 多环境配置(使用多个 YAML 文件)

实际开发中,开发、测试、生产环境的配置可能不同(如端口、环境变量),可通过多个配置文件分离环境差异:

  • 基础配置:compose.yml(通用配置,如服务定义、网络、卷);
  • 环境配置:compose.dev.yml(开发环境)、compose.prod.yml(生产环境)。

启动时通过-f参数指定多个文件,后序文件会覆盖前序文件的同名配置:

# 使用开发环境配置启动
docker compose -f compose.yml -f compose.dev.yml up -d

# 使用生产环境配置启动
docker compose -f compose.yml -f compose.prod.yml up -d

2. 环境变量替换(.env文件)

通过.env文件存储环境变量,在compose.yml中用${变量名}引用,避免硬编码敏感信息(如密码、密钥)。

示例

  • .env文件:
DB_ROOT_PASSWORD=mysecret
WEB_PORT=8080
  • compose.yml中引用:
services:
  web:
    ports:
      - "${WEB_PORT}:80"  # 引用WEB_PORT变量
  db:
    environment:
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}  # 引用密码变量

3. 容器间通信

Compose 自动为同一网络中的服务配置 DNS 解析,容器间可直接通过服务名通信(无需记忆 IP)。例如:

  • web服务要访问db服务的 MySQL,连接地址可写为db:3306(db是服务名);
  • 若服务加入多个网络,需确保通信双方在同一网络中。

4. 依赖管理注意事项

depends_on仅保证启动顺序(先启动依赖的服务),但不保证依赖服务 “已就绪”(如数据库启动但未完成初始化)。解决办法:

  • 在应用代码中添加重试逻辑(如连接数据库失败时重试);
  • 使用第三方工具(如wait-for-it、dockerize)检测依赖服务就绪状态。

5. 生产环境使用建议

  • 避免使用restart: always,改用 Docker Swarm 或 Kubernetes 的健康检查和自动重启策略;
  • 数据卷推荐使用命名卷(而非宿主机路径绑定),便于管理和迁移;
  • 敏感信息(如密码)不要直接写在配置文件,可通过 Docker Secrets 或环境变量注入;
  • 对于大规模应用,Compose 更适合开发测试,生产环境建议使用 Docker Swarm 或 Kubernetes。

六、常见问题与排查

1. 配置文件语法错误

表现:docker compose up时报错yaml: syntax error。
排查:检查缩进(YAML 依赖空格缩进,不能用 Tab)、冒号后是否有空格(如image:nginx错误,应为image: nginx)、列表项是否正确(-后需有空格)。


2. 容器启动后立即退出

表现:docker compose ps显示容器状态为Exited。
排查:查看日志docker compose logs <服务名>,通常是启动命令错误(如command配置有误)或应用依赖未满足(如数据库未就绪)。


3. 容器间无法通信

表现:web服务无法访问db服务。
排查:

  • 确认服务是否在同一网络:docker compose exec web ping db;
  • 检查网络配置:docker network inspect <项目名>_app-net;
  • 确认防火墙是否阻止容器间通信(如宿主机iptables规则)。

4. 数据卷挂载失败

表现:容器内数据未持久化,或提示 “permission denied”。
排查:

  • 检查卷配置是否正确:docker volume inspect <项目名>_mysql-data;
  • 若绑定宿主机目录,确认宿主机目录权限(容器内用户是否有访问权限)。

总结

Docker Compose 通过 “单一配置文件 + 统一命令” 解决了多容器应用的管理难题,其核心是compose.yml配置文件的编写 —— 通过services定义容器、networks配置通信、volumes管理数据。掌握 Compose 的配置语法和常用命令,能极大提升多容器应用的开发、测试效率,是 Docker 生态中不可或缺的工具。实际使用中需注意环境隔离、依赖管理和数据持久化,结合最佳实践可进一步提升配置的灵活性和可靠性。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐