Docker 学习| Docker Compose 多容器编排
前言
前面我们学习了镜像、容器、网络、数据卷。实际业务往往不是单个容器,一套应用会由多个容器共同组成(比如 web+mysql+redis)。 如果手动一个个docker run启动,需要写一大堆参数,还要控制启动顺序、网络、数据卷,操作繁琐、不利于迁移。 Docker Compose 就是用来解决多容器应用编排部署的工具:通过 YAML 配置文件,一次性定义、管理一组关联容器。
核心概念:
- 服务 (service):一个服务对应一个容器
- 项目 (project):一组服务的集合,同一个 yaml 下所有容器属于同一个项目
一、Compose 简介
- Compose 是 Docker 官方开源工具,专门用于定义和运行多容器 Docker 应用。
- 使用步骤三步:
- 用
docker‑compose.yml(或compose.yml)YAML 文件定义应用的各个服务; - 一条命令创建并启动所有服务;
- 使用命令对整套应用进行启停、重启、删除操作。
- 用
- 版本说明:现在新版本 Docker 已经内置 compose 插件,命令为
docker compose(不带横杠);旧版本独立工具是docker‑compose。
二、docker‑compose.yml 配置文件核心字段
yaml 语法注意:缩进非常重要,使用空格,不能用 Tab,冒号后面必须有空格。
常用关键字段:
表格
| 字段 | 作用 |
|---|---|
version |
指定 compose 文件版本(新版本可以省略) |
services |
定义所有应用服务,下面写各个 service |
image |
直接使用现成镜像 |
build |
指定 Dockerfile 路径,自动构建镜像再启动容器 |
ports |
端口映射,格式宿主机端口:容器端口 |
volumes |
数据卷 / 绑定挂载,实现数据持久化 |
networks |
指定容器加入的自定义网络 |
depends_on |
服务依赖,控制容器启动先后顺序(只控制启动顺序,不会等待应用就绪) |
environment |
设置容器环境变量 |
restart |
容器重启策略 |
简单示例模板(web+mysql)
bash
version: "3"
services:
web:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
networks:
- my_net
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "123456"
volumes:
- mysql_data:/var/lib/mysql
networks:
- my_net
volumes:
mysql_data:
networks:
my_net:
说明:
depends_on:‑db:web 服务会等 db 容器先启动,但不会等待 mysql 数据库完全就绪;业务代码需要自己处理数据库连接重试。- volumes 顶层声明:定义 docker 托管数据卷。
- networks 顶层声明:compose 会自动创建自定义网络,同项目下服务可以直接用服务名当做主机名互相访问(内置 DNS)。
三、Compose 常用命令
注意:执行命令必须在
docker‑compose.yml所在目录执行。
bash
# 1.创建并启动所有容器(后台运行‑d)
docker compose up -d
# 2.查看当前项目下服务状态
docker compose ps
# 3.查看日志
docker compose logs -f
# 4.停止服务,容器不删除
docker compose stop
# 5.启动已经停止的服务
docker compose start
# 6.重启全部服务
docker compose restart
# 7.停止并删除容器(数据卷默认不会删除)
docker compose down
# 8.停止删除容器,同时删除数据卷
docker compose down -v
# 9.构建服务镜像(build字段生效)
docker compose build
# 10.扩展副本,横向扩容,启动3个web实例
docker compose up -d --scale web=3
重点说明
docker compose up -d:最常用命令,检测配置变化,变化则重建容器;没有变化直接启动。docker compose down:只删除容器、网络;不会自动删除 volumes 数据卷,防止误删业务数据 ,加‑v才会删除卷。- compose 自动创建独立自定义网络:同一个项目内部,服务名就是 DNS 域名,web 可以直接 ping db,不需要写 IP。
四、depends_on 的坑
depends_on仅仅保证容器启动顺序:先启动 db 容器,再启动 web 容器。 ≠等待 db 里面 mysql 服务完全启动完毕。
场景:mysql 容器进程刚启动,数据库还在初始化,web 容器已经发起数据库连接,直接报错。 ✅解决方案:业务程序增加重试连接逻辑,或者编写脚本循环检测数据库端口是否可访问再执行业务。
五、build 字段:使用 Dockerfile 自动构建镜像
当需要自定义镜像,不需要手动docker build,compose 可以自动构建。
bash
services:
myapp:
build: ./dockerfile_dir # 指定Dockerfile所在目录
# build:
# context: .
# dockerfile: mydockerfile
ports:
- "8080:8080"
执行docker compose up -d,如果镜像不存在,会自动 build 构建。
六、重启策略 restart
no:默认,容器退出不重启always:容器总是自动重启(docker 启动也会拉起)on‑failure:只有异常退出(非 0 返回码)才重启unless‑stopped:除非手动停止,否则一直重启,生产环境常用
示例:
bash
services:
web:
image: nginx
restart: always
七、Compose 项目网络特性
- 执行
docker compose up会自动创建一个项目专属 bridge 网络,所有 service 默认加入该网络。 - 同一 compose 项目内部,服务名称作为主机名直接通信,不需要记 IP,自带 DNS 解析。
- 不同 compose 项目默认网络隔离;想要互通,需要手动指定外部已存在的自定义 network。
小结
- Docker Compose 用来编排一组关联容器,用 YAML 文件统一描述多容器应用,告别大量 docker run 参数。
- 核心文件
compose.yml,关键字段:services、image、build、ports、volumes、depends_on、networks、environment、restart。 - 常用命令:
up‑d、ps、logs、restart、down;down‑v才会删除数据卷。 depends_on只控制容器启动顺序,不会等待业务应用就绪,业务要做连接重试。- Compose 自动创建自定义网络,服务名可直接作为域名互相访问,这是 compose 最大便利点。
- 适合开发、测试环境;大规模生产集群一般使用 Kubernetes。