Docker Compose 多容器编排基础与常用命令详解
Docker Compose 是用于定义和编排多个 Docker 容器的工具。通过 docker-compose.yml 文件配置服务、镜像、网络、卷等资源,实现多容器应用的统一管理。核心概念如服务与项目,解析 key 参数包括 image、command、environment、volumes 等,并介绍常用命令 docker compose up/down/run 的使用方法及依赖控制,助力快速掌握多容器应用编排。

Docker Compose 是用于定义和编排多个 Docker 容器的工具。通过 docker-compose.yml 文件配置服务、镜像、网络、卷等资源,实现多容器应用的统一管理。核心概念如服务与项目,解析 key 参数包括 image、command、environment、volumes 等,并介绍常用命令 docker compose up/down/run 的使用方法及依赖控制,助力快速掌握多容器应用编排。

Docker Compose 是 Docker 官方的开源项目,使用 Python 编写而成;用于定义和编排(管理)多个 Docker 容器,从而运行复杂的应用。
关键概念:
它通过一个名为 docker-compose.yml 的配置文件来定义项目和其中的所有服务;其默认的管理对象是整个项目,可以便捷地对项目内所有容器的生命周期(启动、停止、重建等)进行统一管理;能够轻松地定义和管理由多个相互依赖的服务(如 Web 应用、数据库、缓存等)组成的应用。
docker run 命令或编写复杂脚本,提升效率。docker-compose-plugin 组件。docker-compose.yml 配置文件,定义多个相关联的服务,使它们能在隔离环境中协同运行;执行一条 docker compose up 命令,即可启动和运行整个多服务应用程序(比如哪个容器先启动哪个后启动)。docker-compose 文件都创建自己对应的一个 bridge 网络,把对应的所有服务全部加入到对应的这个网络中,使得所有容器都能互相基于它进行通信。关于不同参数选项用法可以查阅对应文档:
yml 文件基本使用格式:
version 字段指定所使用的 Docker Compose 语法版本(如'3.8')。services 块,用于定义多个应用容器(如 servicename, servicename2)。image: 指定服务所使用的镜像,为必填项。command: 覆盖镜像中默认的启动命令。environment: 设置容器内的环境变量。volumes: 配置数据卷挂载,实现数据持久化或共享。networks: 将服务连接到指定的自定义网络。ports: 将容器端口映射到宿主机端口。expose: 声明容器对外暴露的端口(不映射到宿主机)。build: 指定构建镜像的上下文目录。depends_on: 定义服务之间的启动依赖关系。env_file: 从文件中批量读取环境变量。volumes 和 networks 等独立资源,供各服务使用。注意:
默认 dockercompose 以 yml 所在目录为项目目录;然后就是对应的 yml 缩进是空格格式不是 Tab;缩进代表层级关系,必须使用空格(通常为 2 个空格)并且严格对齐
使用方法:
image: redis。image: redis:5。image: redis@sha256:0ed5...。image: library/redis。image: docker.io/library/redis。image: my_private.registry:5000/redis。下面演示下:
首先创建对应项目目录:
编辑好对应 yml;这里其他选项不填就是默认(对应的服务名字就是项目 - 服务 - 第几个镜像形式呈现)。
发现成功启动默认的 nginx 容器。
用于覆盖 Docker 容器镜像中设定的默认启动命令;在 Docker Compose 文件或 Dockerfile 中,通过 command 指令来定义新的启动命令。
两种写法:
command: ["bundle", "exec", "thin", "-p", "3000"]。command: bundle exec thin -p 3000。应用场景:常见于需要自定义服务启动参数的情况,例如为 Web 服务器指定运行端口、为应用传递特定环境变量等。
演示下:
这里因为覆盖掉 command 的命令了,默认 nginx 就不是后台运行,所以运行下就停止了。
查看容器详情 Cmd 被覆盖了。
entrypoint 指令用于覆盖 Docker 容器镜像中默认的启动入口点(也就是主命令)。
使用格式:
entrypoint: /code/entrypoint.sh),作为容器启动时运行的入口程序。entrypoint: [ "php", "-d", "zend_extension=...", "-d", "memory_limit=-1", "vendor/bin/phpunit" ]),精确控制启动行为。entrypoint 和 command 本身不会冲突,它们是组合关系,共同组合来执行命令。应用场景:适用于需要自定义容器初始化流程或复杂命令参数的场景,例如设置特定扩展、配置运行参数后再启动主程序。
演示下:
启动成功。
查看容器详情发现对应的 cmd 为空,然后 entrypoint 就是这个要执行的命令,所以执行对应前台进程,保持 nginx 稳定运行不退出。
注意:
如果是后台进程的话,docker 就会默认它启动完已经执行完了,立马让它 exited 状态,但是如果是前台进程,相当于占用控制台,一直在前台跑,docker 就不会认为容器主进程已经执行完了,所以就不会让它直接退出;所以 docker 中的 nginx 默认启动就是前台进程,不会直接挂掉。
用于在 Docker Compose 配置中为服务设置环境变量;支持映射(字典)和数组两种语法格式来定义变量;若值为布尔类型(如 true/false),必须用引号包裹,防止 YAML 解析器将其转换为 Python 的 True/False。
格式:
RACK_ENV: developmentSHOW: "true"- RACK_ENV=development- SHOW=true演示下:
运行成功,查看 config 也是没报错返回。
环境变量也是被添加进入容器了。
给容器分组,配置谁能和谁通信;隔离容器通信权限,实现分组管控。
用法 (在 docker-compose.yml 里):
services:
web:
# 服务 1
image: nginx
networks:
- frontend # 加入前端网络组
- backend # 同时加入后端网络组
db:
# 服务 2
image: mysql
networks:
- backend # 仅加入后端网络组
networks:
frontend:
# 网络组 1(前端专用)
driver: bridge # 使用桥接模式(默认)
backend:
# 网络组 2(后端专用)
driver: bridge
演示下:
把电脑上的文件夹或文件,映射到容器内部,实现数据同步和持久化。
简单写法
volumes:
- "电脑路径:容器路径" # 冒号左边是电脑上的位置,右边是容器里的位置
volumes:
- type: volume # 类型:volume (docker 管理的卷) | bind (你电脑的路径)
source: 来源名 # 卷名 或 电脑上的具体路径
target: 容器路径 # 容器里出现的路径
volumes:
# 表明主机的目录位置(比如命名卷)
name:
核心就一点:电脑(源):容器(目标)
演示下:
可以看到自动识别对的绑定卷。
compose 运行成功。
这里因为宿主机对应绑定目录是空给容器覆盖了。
进行同步成功,对应 html 出现内容。
1.精细控制:
ports:
- target: 80 # 容器内端口
host_ip: 127.0.0.1 # 宿主机绑定 IP(默认所有 IP)
published: 8080 # 宿主机映射端口
protocol: tcp # 协议类型(tcp/udp)
mode: host # 模式(host/ingress)
2.短语法格式:
ports:
- "8000:8000" # 主机端口:容器端口
- "3000" # 随机主机端口→容器 3000 端口
- "127.0.0.1:5000:5000" # 指定 IP 映射
- "6060:6060/udp" # UDP 协议映射
- "9090-9091:8080-8081" # 端口段批量映射
演示下:
expose 用于声明容器内部监听的端口,仅允许同一网络下的其他容器访问,不会映射到宿主机 ;在服务配置下以列表形式声明内部端口号(支持字符串或数字格式)。
用法:
services:
app:
image: your-app
expose:
- "3000" # 暴露 3000 端口(推荐字符串格式)
- 8000 # 暴露 8000 端口(数字格式也可)
暴露的端口只能被同一 Docker 网络内的其他服务访问,外部主机和宿主机均无法直接访问;通常用于微服务间内部通信(如后端服务暴露 API 端口供前端服务内部调用)。
演示下:
用于指定为构建镜像上下文路径。
services:
服务名:
build:
context: . # 必填:Dockerfile 所在目录(`.`表示当前目录)
dockerfile: Dockerfile # 可选:自定义 Dockerfile 文件名
args:
# 可选:构建时传递变量
KEY: value
使用如:
services:
webapp:
build: . # 最短写法:直接指定上下文目录
api:
build:
context: ./backend # 指定子目录
dockerfile: dev.Dockerfile # 使用非标准文件名
args:
NODE_ENV: production
这里用法后面的 dockerfile 会用到。
depends_on 指令用于定义服务间的启动依赖顺序。为了让依赖控制更精确,可以配合 healthcheck 健康检查,确保不仅依赖服务已启动,而且其内部应用已准备就绪。
1.基础依赖(仅控制启动顺序)
services:
web:
depends_on:
- db # 先启动 db,再启动 web
- redis # 先启动 redis,再启动 web
2.高级依赖(等待服务就绪)
通过 condition: service_healthy 指定必须等待依赖服务通过健康检查后,才启动当前服务。这必须配合 healthcheck 配置使用。
services:
web:
depends_on:
db:
condition: service_healthy # 必须等待 db 服务健康
db:
image: mysql
healthcheck:
# 定义健康检查
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s # 每 10 秒检查一次
timeout: 5s # 检查超时时间
retries: 10 # 失败重试次数
3.健康检查 (healthcheck) 参数说明
test: 检查命令,如 ["CMD", "curl", "-f", "http://localhost"]interval: 检查间隔(如 30s)timeout: 单次检查超时时间(如 5s)retries: 连续失败次数达到后标记为不健康演示下:
这里发现是先启动的 mysql 健康后,才启动的 web 服务(创建成功和启动成功不一样)。
这里发现先先停止 web 才停止 mysql;因为 web 依赖 mysql 运行。
env_file 关键字直接指定一个环境变量文件路径(如 env_file: .env)。- ./common.env)。./common.env)和绝对路径(如 /opt/secrets.env)。演示下:
成功运行成功,导入环境变量。
两个文件的环境变量都被合并导入了。
| 命令 | 功能 | 备注 |
|---|---|---|
docker compose build | 构建服务 | |
docker compose config | 规范的格式来显示服务配置 | |
docker compose cp | 在本地系统和服务容器直接拷贝文件 | |
docker compose create | 创建服务的容器 | |
docker compose down | 停止所有容器,并删除容器 | |
docker compose events | 从服务器获取实时事件 | |
docker compose exec | 在容器中执行命令 | |
docker compose images | 列出所有容器使用的镜像 | |
docker compose kill | 强制停止服务的容器 | |
docker compose logs | 显示日志 | |
docker compose ls | 显示所有项目 | |
docker compose pause | 暂停服务 | |
docker compose port | 列出所有的端口映射 | |
docker compose ps | 该命令可以列出项目中目前的所有容器 | |
docker compose pull | 拉取服务镜像 | |
docker compose push | 推送服务镜像 | |
docker compose restart | 重启或者重启某个服务 | |
docker compose rm | 删除服务停止的容器 | |
docker compose run | 在指定服务容器上执行相关的命令 | |
docker compose start | 启动当前停止的某个容器 | |
docker compose stop | 停止当前运行的某个容器 | |
docker compose top | 显示运行的进程 | |
docker compose unpause | 恢复服务 | |
docker compose up | up 命令会构建,(重新) 创建,启动,链接一个服务相关的容器。默认情况下如果容器已经存在,将会停止并尝试重新创建他们。并使用之前挂载的卷。-no-recreate 参数可以让容器不被停止或者重新创建,-d 表示后台运行 | |
docker compose version |
详细可查看:官方文档
很多命令都和对应的 docker 的差不多,下面选择一些不一样的命令介绍。
1.基本结构
docker compose [选项] 命令 [参数]
2.最常用选项
-f:指定配置文件(默认用当前目录的 docker-compose.yml)-p:给项目起个名(默认用当前文件夹名)3.使用示例
# 最简单的启动
docker compose up
# 指定配置文件和项目名
docker compose -f my-app.yml -p myproject up
# 后台启动
docker compose up -d
先写选项,再选命令,最后加参数!
演示下:
docker compose up 是核心启动命令,能自动完成构建镜像、创建服务、启动容器并关联依赖项的全流程。-d 选项让容器在后台运行,这是生产环境的推荐用法。--force-recreate:强制重建容器(即使已存在)。--no-recreate:若容器已存在则跳过重建(与上述选项互斥)。web db),仅启动部分服务。演示下:
容器已经存在,还强制创建新的进行覆盖。
已经存在该些容器了,不再创建直接运行。
docker compose down 命令用于停止并删除由 docker compose up 创建的所有容器和网络。docker compose down [options] [SERVICE...],支持添加选项和指定部分服务。-v:使用 -v 或 --volumes 选项可在删除容器的同时,删除其关联的所有命名卷和匿名卷(数据卷),实现彻底清理(只清理容器管理(docker 管理的对应 volumes 下内容),不清理宿主机的内容)。[SERVICE...] 参数指定仅删除部分服务(如 docker compose down web db),而非全部服务。演示下:
命名卷测试:
命名卷启动,发现对应的内容同步过来了。
没有 -v,停止删除掉所有服务,发现对应内容还在。
加上 -v 选项后,发现被 docker 管理的命名卷目录下的对应目录及内容就消失了。
绑定卷测试(Redis 服务没有定义任何卷挂载,但 Redis 官方镜像在 Dockerfile 中默认声明了数据卷,也就是说 volume 看到的卷是 redis 的匿名卷,而绑定卷是看不到的):
首先进行运行起来。
可以发现有四个匿名的匿名卷。
无 -v 选项发现对应的卷还在。
下面再次重新启动下:
发现对应的被创建成功。
也位于对的 docker 管理 volumes 的路径下,有对应的标记。
这里发现当 -v 后,对应的 docker 关于匿名卷的信息会删除(比如对应的 docker 对 volume 的管理标记,但是宿主机上之前映射内容还是会存在的(因为这是绑定卷,不受 -v 控制)。)
因此总结下:
docker compose down -v 只清理 Docker 自己管理的资源(容器、网络、命名卷 匿名卷等,对临时卷 绑定卷无效),而不会动宿主机上的任何文件(比如它不会删除对的绑定卷内容,而会删除对应的 /var/lib/docker/volumes 目录下内容,因为它是绑定卷,不受 volume 控制)。
docker compose run [选项] 服务名 [命令] [参数...]。-d:让容器在后台运行。--name:为本次运行的容器指定一个名字。--entrypoint:覆盖容器默认的启动命令。-e:设置环境变量(可多次使用)。-u:指定运行命令的用户名或 UID。--rm:命令执行后自动删除容器。-p:将容器端口映射到主机。演示下:
通过学习本文可以知道 Docker Compose 是多容器应用的一站式管理工具,通过 yml 文件定义服务依赖与资源配置,结合 up/down 等命令实现高效编排,从开发到测试均可简化流程,是容器化部署的实用利器。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online
| 查看版本 |