Skip to content

第 8 章 Docker Compose:一键编排多容器 ​

本章目标:掌握 compose.yaml 的结构与常用指令,理解它与 docker run 的对应关系,能一条命令启动/管理多服务应用。

1. 为什么需要 Compose ​

真实应用很少只有一个容器:Web 服务 + 数据库 + 缓存 + 消息队列……用 docker run 一条条敲,问题立刻显现:

  • 命令又长又乱,端口、环境变量、卷、网络反复写;
  • 忘记加 --network,容器间就连不上;
  • 团队协作时每个人手敲的启动方式都不一样。

Compose 把"应用由哪些服务组成"声明式地写进一个 YAML 文件(compose.yaml),docker compose up -d 一条命令启动全部,down 一键清理。Compose 是单机编排的标准方式(多机编排是后面的事,如 Swarm/K8s)。

2. compose.yaml 的结构 ​

yaml
services:        # 服务列表:一个服务 ≈ 一个容器
  web:           # 服务名(同时是网络内的域名)
    image: nginx:alpine
    ports:
      - "8086:80"
  cache:
    image: redis:7-alpine

networks:        # 自定义网络(可选,不写也会自动创建默认网络)
  default:
    driver: bridge

volumes:         # 具名卷(可选)
  db-data:

要点:

  • services 是唯一必填的顶层键;networks/volumes 不写时 Compose 也会自动创建默认网络/匿名卷;
  • 服务名即域名:同一项目内,服务之间直接用服务名访问(redis、web),自动获得第 5 章讲的容器名 DNS 解析;
  • 现代 Compose 不再需要 version: 字段(写了对新版本反而是警告)。

3. 服务字段:与 docker run 的对应 ​

Compose 字段基本就是 docker run 选项的声明式翻译:

docker runcompose.yaml(服务字段)说明
-p 8086:80ports: ["8086:80"]端口映射(列表)
-e KEY=valenvironment: [KEY=val] 或 map环境变量
-v 卷:/路径volumes: ["卷:/路径"]挂载(卷名或相对路径)
--network xnetworks: [x]加入的网络
--restart xrestart: x重启策略
--name ncontainer_name: n(一般不写,让 compose 命名)容器名
—depends_on:声明服务依赖与启动顺序
—healthcheck:健康检查(配合 depends_on 条件启动)
docker buildbuild: . + image: 名本地构建(第 6 章)

depends_on 的两种用法:

yaml
services:
  web:
    depends_on:
      - db            # 简单版:只保证 db 先启动(不保证就绪)
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    healthcheck:      # 健康检查:mysqladmin ping 通才算"健康"
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-psecret"]
      interval: 5s
      timeout: 3s
      retries: 10
  app:
    depends_on:
      db:
        condition: service_healthy   # 进阶版:等 db 健康后再启动 app

depends_on 只解决"启动顺序",不保证依赖"就绪";要等就绪必须配合 healthcheck + condition: service_healthy。

4. 常用命令 ​

bash
docker compose up -d          # 启动全部服务(后台;首次会自动构建/拉取)
docker compose up -d --build  # 构建后启动(改了 Dockerfile/代码时用)
docker compose ps             # 查看服务状态
docker compose logs -f web    # 跟踪某个服务的日志
docker compose exec web sh    # 进入某个服务
docker compose config         # 校验并展开最终的 compose 配置(排错利器)
docker compose pull           # 拉取所有镜像
docker compose down           # 停止并删除容器(默认保留卷)
docker compose down -v        # 连具名卷一起删除(数据没了,慎用!)

关键区别:

  • up 与 run:up 启动的是"长期服务";docker compose run web cmd 是临时跑一次命令;
  • down 与 stop:down 删容器(保留卷),stop 只停;
  • down -v 会删卷——数据库数据一并清除,只应在确定不要数据时使用。

5. 完整示例:三服务应用(本机可复现) ​

配套 examples/08-docker-compose/,全部镜像已在本地,秒级启动:

yaml
# examples/08-docker-compose/compose.yaml
services:
  web:
    image: nginx:alpine
    ports:
      - "8086:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - cache
      - app
  cache:
    image: redis:7-alpine
  app:
    image: alpine
    command: ["sh", "-c", "sleep 300"]
    depends_on:
      cache:
        condition: service_started

启动并验证(服务名即域名):

bash
cd examples/08-docker-compose
docker compose up -d
docker compose ps                      # 三个服务都 running
curl http://localhost:8086/            # web 可访问
docker compose exec app ping -c 1 cache   # app 里按服务名 ping 通 redis
docker compose logs --tail 5 web       # 看 web 日志
docker compose down                    # 一键清理

扩展:加数据库只需在 services 下追加 db 服务(image: mysql:8.0 + environment + healthcheck),并让依赖它的服务 depends_on: db: {condition: service_healthy}——Compose 的编排能力让"加一个服务"变成"加几行 YAML"。

常见误区 ​

  • 误区:depends_on 能保证依赖就绪。 正确:它只保证启动顺序;要等就绪必须 healthcheck + condition: service_healthy。
  • 误区:down 会清掉数据。 正确:down 保留具名卷;down -v 才会删卷,慎用。
  • 误区:compose.yaml 必须写 version: '3'。 正确:现代 Compose 已不需要 version 字段。
  • 误区:不同服务之间用 localhost 访问。 正确:服务间通信用服务名(http://web:80),localhost 只指容器自身。
  • 误区:docker compose 和 docker-compose 一样。 正确:docker compose 是 Compose v2(集成进 docker CLI);docker-compose 是独立的 v1 老工具,新项目用 v2。

小结 ​

  • Compose = 用 YAML 声明式描述多服务应用,up -d 一键启动、down 一键清理。
  • 结构:services(必填)+ networks/volumes(可选);服务名即网络内域名。
  • 服务字段与 docker run 选项一一对应(ports/environment/volumes/restart/depends_on/healthcheck)。
  • depends_on 管顺序,healthcheck + condition: service_healthy 管就绪。
  • down 保留卷,down -v 删卷(慎用);docker compose config 校验配置。

练习 ​

  1. 在 examples/08-docker-compose/ 运行 docker compose up -d,用 docker compose ps 观察三个服务的状态。
  2. 用 docker compose exec app ping -c 1 cache 验证服务名 DNS 解析;再试 ping -c 1 web,理解 compose 自动网络。
  3. 在 compose.yaml 中给 web 加 healthcheck(如 wget -q --spider http://localhost/),用 docker compose ps 观察健康状态列。
  4. 分别执行 docker compose down 与 docker compose down -v,对比 docker volume ls 的变化,理解 -v 的破坏性。
  5. 思考题:为什么说"服务之间用 localhost 互相访问"是常见的错误?(提示:localhost 在容器里指的是容器自己。)

可运行示例见 examples/08-docker-compose/,按其中的 README 步骤执行。

📖本文阅读--次|📊全站访问--次|👥访客--人