Docker Compose入门级别教学:一键搞定多容器编排基础,yml配置+部分常用命令全解析,有了它再也不用担心不会用docker compose了!

本篇摘要
本文详解Docker Compose核心概念与用法,涵盖服务/项目定义、yml文件参数(如image/command/networks等)、常用命令(up/down/run等),通过图文演示环境搭建与配置技巧,助力快速掌握多容器应用编排。
一.Docker Compose(容器编排)
概念介绍
Docker Compose 是 Docker 官方的开源项目,使用 Python 编写而成;用于定义和编排(管理)多个 Docker 容器,从而运行复杂的应用。
关键概念:
- 服务 (Service):代表一个应用的容器,可以是由相同镜像创建的多个容器实例。
- 项目 (Project):代表一个完整的业务单元,由一组关联的应用容器共同组成。

它通过一个名为 docker-compose.yml 的配置文件来定义项目和其中的所有服务;其默认的管理对象是整个项目,可以便捷地对项目内所有容器的生命周期(启动、停止、重建等)进行统一管理;能够轻松地定义和管理由多个相互依赖的服务(如 Web 应用、数据库、缓存等)组成的应用。
为啥需要Docker Compose
- Docker 官方建议每个容器只运行一个进程(如应用、数据库、Nginx 各自独立);现代应用通常由多个服务组成,需要同时启动和管理多个容器。
- 避免多次手动执行
docker run命令或编写复杂脚本,提升效率。 - 将分散的关联容器整合为一个整体项目,方便统一编排和管理。
Docker Compose 功能
-
安装docker的时候默认安装了
docker-compose-plugin组件。 -
通过一个
docker-compose.yml配置文件,定义多个相关联的服务,使它们能在隔离环境中协同运行;执行一条docker compose up命令,即可启动和运行整个多服务应用程序(比如哪个容器先启动哪个后启动)。 -
提供命令来统一管理应用的生命周期,包括启动、停止和重新构建服务。
-
可以方便地查看所有正在运行的服务的状态;能够实时流式传输(查看)所有服务的日志输出;支持在某个服务中运行一次性命令,便于调试或管理。
-
默认每个
docker-compose文件都创建自己对应的一个bridge网络,把对应的所有服务全部加入到对应的这个网络中,使得所有容器都能互相基于它进行通信。
Docker Compose 使用场景
- 单主机快速部署:用于在单台机器上快速搭建和运行开发或测试环境,简单便捷。
- 实现环境隔离:通过指定不同的项目(project)名称,可以在同一主机上隔离运行多个互不干扰的环境。
二.Docker Compose 文件(docker-compose.yml)解析
关于不同参数选项用法可以查阅对应文档:

yml文件基本使用格式:
- 版本声明:文件开头通过
version字段指定所使用的 Docker Compose 语法版本(如 “3.8”)。 - 服务定义:核心部分是
services块,用于定义多个应用容器(如 servicename, servicename2)。 - 服务配置项:每个服务下可配置多个关键指令:
image: 指定服务所使用的镜像,为必填项。command: 覆盖镜像中默认的启动命令。environment: 设置容器内的环境变量。volumes: 配置数据卷挂载,实现数据持久化或共享。networks: 将服务连接到指定的自定义网络。ports: 将容器端口映射到宿主机端口。expose: 声明容器对外暴露的端口(不映射到宿主机)。build: 指定构建镜像的上下文目录。depends_on: 定义服务之间的启动依赖关系。env_file: 从文件中批量读取环境变量。
- 顶级资源定义:除了服务,还可以在顶层定义
volumes和networks等独立资源,供各服务使用。 - 服务发现:服务名称(servicename)可作为容器间网络通信的内部 DNS 名称直接使用。
注意:
默认dockercompose以yml所在目录为项目目录;然后就是对应的yml缩进是空格格式不是Tab;
缩进代表层级关系,必须使用空格(通常为2个空格)并且严格对齐
1·image选项
使用方法:
- 仅镜像名:使用官方镜像仓库中的镜像名称,如
image: redis。 - 镜像名+标签:在名称后指定版本标签,如
image: redis:5。 - 镜像摘要:使用唯一的哈希值(SHA256)精确锁定镜像版本,如
image: redis@sha256:0ed5...。 - 仓库路径:指定镜像在仓库中的命名空间路径,如
image: library/redis。 - 完整仓库地址:包含注册服务器地址的完整路径,如
image: docker.io/library/redis。 - 私有仓库镜像:使用私有仓库地址及端口拉取镜像,如
image: my_private.registry:5000/redis。
下面演示下:
首先创建对应项目目录:


- 编辑好对应yml;这里其他选项不填就是默认(对应的服务名字就是项目-服务-第几个镜像形式呈现)。


- 发现成功启动默认的nginx容器。
2·command选项
用于覆盖 Docker 容器镜像中设定的默认启动命令;在 Docker Compose 文件或 Dockerfile 中,通过 command 指令来定义新的启动命令。
两种写法:
- 列表格式:使用 JSON 数组形式,例如
command: ["bundle", "exec", "thin", "-p", "3000"]。 - 字符串格式:直接书写命令字符串,例如
command: bundle exec thin -p 3000。
应用场景:常见于需要自定义服务启动参数的情况,例如为 Web 服务器指定运行端口、为应用传递特定环境变量等。
演示下:


- 这里因为覆盖掉command的命令了,默认nginx就不是后台运行,所以运行下就停止了。

- 查看容器详情Cmd被覆盖了。
3.entrypoint选项
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默认启动就是前台进程,不会直接挂掉。
4.environment选项
用于在 Docker Compose 配置中为服务设置环境变量;支持映射(字典)和数组两种语法格式来定义变量;若值为布尔类型(如 true/false),必须用引号包裹,防止 YAML 解析器将其转换为 Python 的 True/False。
格式:
- 使用缩进的键值对形式,例如:
RACK_ENV: developmentSHOW: "true"
- 数组语法示例:使用短横线列表形式,变量通过等号赋值,例如:
- RACK_ENV=development- SHOW=true
演示下:


- 运行成功,查看config也是没报错返回。

- 环境变量也是被添加进入容器了。
5.networks选项
给容器分组,配置谁能和谁通信;隔离容器通信权限,实现分组管控。
用法 (在 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
演示下:



- 对应运行成功,容器网络也被添加。
6.volumes选项
把电脑上的文件夹或文件,映射到容器内部,实现数据同步和持久化。
-
简单写法
volumes: - "电脑路径:容器路径" # 冒号左边是电脑上的位置,右边是容器里的位置 -
复杂写法
volumes:
- type: volume # 类型:volume (docker管理的卷) | bind (你电脑的路径)
source: 来源名 # 卷名 或 电脑上的具体路径
target: 容器路径 # 容器里出现的路径
volumes: # 表明主机的目录位置(比如命名卷)
name:
核心就一点:电脑(源):容器(目标)
演示下:


- 可以看到自动识别对的绑定卷。

- compose运行成功。

- 这里因为宿主机对应绑定目录是空给容器覆盖了。

- 进行同步成功,对应html出现内容。
7.ports选项
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" # 端口段批量映射
演示下:


- 成功完成宿主机与主机映射。
8.expose选项
expose 用于声明容器内部监听的端口,仅允许同一网络下的其他容器访问,不会映射到宿主机 ;在服务配置下以列表形式声明内部端口号(支持字符串或数字格式)。
用法:
services:
app:
image: your-app
expose:
- "3000" # 暴露3000端口(推荐字符串格式)
- 8000 # 暴露8000端口(数字格式也可)
暴露的端口只能被同一 Docker 网络内的其他服务访问,外部主机和宿主机均无法直接访问;通常用于微服务间内部通信(如后端服务暴露API端口供前端服务内部调用)。
演示下:



- 这里并没有完成主机与容器端口映射,只是说了下容器要暴露的是80端口。
9.build 选项
用于指定为构建镜像上下文路径。
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会用到。
10. depends_on 选项
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运行。
11. env_file 选项
- 单一文件格式:使用
env_file关键字直接指定一个环境变量文件路径(如env_file: .env)。 - 列表格式:使用列表形式指定多个环境变量文件,按顺序加载(如
- ./common.env)。 - 路径类型:支持相对路径(如
./common.env)和绝对路径(如/opt/secrets.env)。 - 文件作用:将指定文件中的环境变量批量注入到容器中,避免在配置文件中硬编码。
演示下:


- 成功运行成功,导入环境变量。


- 两个文件的环境变量都被合并导入了。
三.docker compose 命令
命令清单
| 命令 | 功能 | 备注 |
|---|---|---|
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 命令格式
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
先写选项,再选命令,最后加参数!
演示下:

2·docker compose up命令
- 核心功能:
docker compose up是核心启动命令,能自动完成构建镜像、创建服务、启动容器并关联依赖项的全流程。 - 后台运行:使用
-d选项让容器在后台运行,这是生产环境的推荐用法。 - 容器重建控制:
--force-recreate:强制重建容器(即使已存在)。--no-recreate:若容器已存在则跳过重建(与上述选项互斥)。
- 服务选择:支持在命令末尾指定具体服务名(如
web db),仅启动部分服务。
演示下:

- 容器已经存在,还强制创建新的进行覆盖。

- 已经存在该些容器了,不再创建直接运行。
3·docker compose down命令
- 核心功能:
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控制)。
4·docker compose run命令
- 命令功能:在指定服务的容器内
执行一次性命令。 - 基本格式:
docker compose run [选项] 服务名 [命令] [参数...]。 - 常用选项:
-d:让容器在后台运行。--name:为本次运行的容器指定一个名字。--entrypoint:覆盖容器默认的启动命令。-e:设置环境变量(可多次使用)。-u:指定运行命令的用户名或UID。--rm:命令执行后自动删除容器。-p:将容器端口映射到主机。
演示下:



- 可以发现需要指定对应的服务名称而不是镜像,然后后面加上要在容器中执行对应的命令;这里发现容器执行完命令就退出来,因为后面执行的命令覆盖了默认的前台启动命令,docker就以为执行完了,就退出来了(这里必须换个yml;因为之前的那个yml的新的entrypoint把旧的(有sh可以接受对应输入命令)给覆盖了,不能执行所有输入的命令)。
文末配置代码汇总:
四.本篇小结
通过学习本文可以知道Docker Compose是多容器应用的一站式管理工具,通过yml文件定义服务依赖与资源配置,结合up/down等命令实现高效编排,从开发到测试均可简化流程,是容器化部署的实用利器。
更多推荐
所有评论(0)