一、简介

Docker Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。

通过第一部分中的介绍,我们知道使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

Docker Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Docker Compose 中有两个重要的概念:

  • 🐚 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
  • 🐌 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

可见,一个项目可以由多个服务(容器)关联而成,Docker Compose 面向项目进行管理,如下如所示:

image.png

二、安装与卸载

查看是否安装 docker compose 命令

1
docker compose version

1、通过 yum 安装与卸载 docker compose

✈️ 安装

1
2
3
4
5
# 安装更新
yum update

# 安装 docker compose 包
yum install -y docker-compose-plugin

🪂 卸载

1
yum remove -y docker-compose-plugin

2、手动安装与卸载 docker compose

✈️ 安装

1
2
3
4
5
6
7
8
# 创建安装目录
mkdir -p /usr/local/lib/docker/cli-plugins

# 下载配置文件
curl -SL https://github.com/docker/compose/releases/download/v2.10.2/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose

# 赋予执行权限
chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

🪂 卸载

1
rm -rf /usr/local/lib/docker/cli-plugins/docker-compose

三、compose 常用模板命令

模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 docker run 相关参数的含义都是类似的。

默认的模板文件名称为 compose.yaml(首选)或 compose.yml,格式为 YAML 格式。Compose 实现还应该支持 docker-compose.yamldocker-compose.yml 以实现向后兼容性。如果两个文件都存在,则 Compose 实现必须更喜欢规范的 compose.yaml 之一。

注意:每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)等来自动构建生成镜像。如果使用 build 指令,在 Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在 compose.yml 中重复设置。

Docker Compose 的 YAML 文件包含 4 个一级 key : version、services、networks、volumes。

下面分别介绍常用各个指令的用法。完整的 docker compose 模板命令参考官方文档:https://docs.docker.com/compose/compose-file/

1、顶级元素 Version

Version: 定义了 Compose 文件格式(主要是 API)的版本,总是位于第一行。

1
version: "3"

2、顶级元素 Services

Services:定义容器或服务的配置文件。

(1)build

build:指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

1
2
3
4
5
6
7
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1

说明:

  • context 指令指定 Dockerfile 所在文件夹的路径。

  • dockerfile 指令指定 Dockerfile 文件名。

  • arg 指令指定构建镜像时的变量。

(2)command

command:覆盖容器镜像(即 Dockerfile 的)声明的默认命令。

1
2
3
command: bundle exec thin -p 3000

command: ["bundle", "exec", "thin", "-p", "3000"]

(3)container_name

container_name:指定自定义容器名称(而不是生成的默认名称)的字符串。

1
container_name: my-web-container

(4)depends_on

depends_on:表示服务之间的启动和关闭依赖关系。

  • 🎸 Compose 创建服务必须按依赖顺序 db redis web 进行创建。
  • 🎺 Compose 删除服务必须按依赖顺序 web db redis 进行删除。
1
2
3
4
5
6
7
8
9
10
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres

(5)dns

dns:定义了要在容器网络接口配置上设置的自定义 DNS 服务器。 可以是单个值或列表。

1
2
3
4
5
dns: 8.8.8.8

dns:
- 8.8.8.8
- 9.9.9.9

(6)environment

environment:用来给容器启动指定的环境变量,相当于 docker run -e 选项。

1
2
3
4
5
6
7
8
9
10
11
# 映射语法
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:

# 数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT

(7)env_file

env_file:根据文件内容向容器添加环境变量。

1
env_file: .env

(8)expose

expose:定义 compose 从容器中公开的端口。

1
2
3
expose:
- "3000"
- "8000"

注:以上指令将当前容器的端口3000和8000暴露给其他容器,和 ports 的区别是,expose 不会将端口暴露给主机,主机无法访问 expose 的端口。

(9)extra_hosts

extra_hosts:将添加主机名映射添加到到容器网络接口配置(/etc/hosts for Linux)。值必须以 HOSTNAME:IP 的形式为其他主机设置主机名和 IP 地址。

1
2
3
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"

(10)image

image:指定容器启动的镜像。

1
2
3
4
5
6
image: redis
image: redis:5
image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis

(11)network_mode

network_mode:设置容器网络模式,可用参数如下:

  • none:禁用所有容器网络
  • host:它为容器提供对主机网络接口的原始访问权限
  • service:{name}:只允许容器访问指定的服务
1
2
3
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"

(12)networks

networks:定义容器使用的网络。

1
2
3
networks:
- some-network
- other-network

(13)ports

ports:暴露容器端口到主机的任意端口或指定端口,用法:

1
2
3
4
ports:
- "80:80" # 绑定容器的80端口到主机的80端口
- "9000:80" # 绑定容器的80端口到主机的9000端口
- "443" # 绑定容器的443端口到主机的任意端口,容器启动时随机分配绑定的主机端口号

注:不管是否指定主机端口,使用ports都会将端口暴露给主机和其他容器

(14)restart

restart:定义了平台将在容器终止时应用的策略

  • no:默认重启策略,在任何情况下都不会重新启动容器。
  • always:该策略会始终重启容器,直到容器删除。
  • no-failure:如果退出代码指示错误,策略将重新启动容器。
  • unless-stopped:该策略会重新启动容器,而不考虑退出代码,但会在服务停止或删除时停止重新启动。
1
2
3
4
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

(15)volumes

volumes:定义容器数据卷挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
services:
backend:
image: awesome/backend
volumes:
- type: volume
source: db-data
target: /data
volume:
nocopy: true
- type: bind
source: /var/run/postgres/postgres.sock
target: /var/run/postgres/postgres.sock

volumes:
db-data:

短语法模式:

1
2
3
# 语法
volume:CONTAINER_PATH
volume:CONTAINER_PATH:access_mode
  • volume:可以是平台托管容器(bind mount)上的主机路径,也可以是卷名

  • CONTAINER_PATH:挂载卷的容器中的路径

  • ACCESS_MODE:是以逗号分隔的选项列表,可以设置为:

    • rw:读写访问权限(默认)
    • ro:只读访问

(16)volumes_from

volumes_from:从另一个服务或容器挂载所有容器卷,可以选择指定只读访问(ro)或读写(rw)。如果未指定访问级别,则必须使用读写。

1
2
3
4
5
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw

(17)working_dir

working_dir: 从 image 指定的目录覆盖容器的工作目录(即Dockerfile WORKDIR)。

3、顶级元素 Networks

networks:用于指引 Docker 创建新的网络。默认情况下,Docker Compose 会创建 bridge 网络。 这是一种单主机网络,只能够实现同一主机上容器的连接。当然,也可以使用 driver 属性来指定不同的网络类型。

在下面的示例中,在运行时,将创建网络前端和后端,并将前端服务连接到前端网络和后端网络。

1
2
3
4
5
6
7
8
9
10
services:
frontend:
image: awesome/webapp
networks:
- front-tier
- back-tier

networks:
front-tier:
back-tier:

4、顶级元素 Volumes

volumes:用于指引 Docker 来创建新的卷。

卷部分允许配置可跨多个服务重用的命名卷。下面是一个双服务设置的示例,其中数据库的数据目录作为名为 db-data 的卷与另一个服务共享,以便可以定期备份:

1
2
3
4
5
6
7
8
9
10
11
12
13
services:
backend:
image: awesome/database
volumes:
- db-data:/etc/data

backup:
image: backup-service
volumes:
- db-data:/var/lib/backup/data

volumes:
db-data:

四、compose 常用命令

命令 说明
up 创建和启动容器
down 删除容器、网络、数据卷和镜像
build 重新构建服务
ps 列出容器
exec 进入容器,在容器里面执行命令
top 显示容器进程
logs 查看容器日志
pause、unpause 暂停、恢复整个项目所有服务或指定服务
rm 删除整个项目或者指定服务
start、stop、restart 开始、停止、重启整个项目所有服务或指定服务
ls 列出正在运行的 compose 项目
version 列出 compose 版本

1、up

​ 为服务构建、(重新)创建、启动和附加到容器。该命令聚合每个容器的输出(像 does 一样)。当命令退出时,所有容器都将停止。-d 参数将在后台启动并运行容器。

1
2
# 语法
docker compose up [OPTIONS] [SERVICE...]

Options

选项 描述
–abort-on-container-exit 如果任何容器被停止,则停止所有容器。注意:不兼容 -d
–always-recreate-deps 重新创建容器依赖。注意不兼容 --no-recreate
–attach 附加到服务输出。
–attach-dependencies 附加到相关容器。
–build 在启动容器之前构建镜像。
–detach,-d 分离模式:在后台运行容器
–exit-code-from 返回所选服务容器的退出代码。意味着 --abort-on-container-exit
–force-recreate 重新创建容器,即使它们的配置和镜像没有更改。
–no-build 即使镜像缺失,也不构建这个容器
–no-color 使用单色输出
–no-deps 不要启动链接服务
–no-log-prefix 不要打印日志前缀
–no-recreate 如果容器已经存在,就不要重新创建它们。不兼容 --force-recreate
–no-start 创建容器后不要启动服务
–pull 运行前提取镜像 (“always”、“missing”、“never”) ,默认值为 missing
–quiet-pull 拉取镜像时,不要打印镜像信息。
–remove-orphans 为没有在 Compose 文件中定义的服务删除容器。
–renew-anon-volumes,-V 重新创建匿名卷,而不是从以前的容器检索数据。
–timeout,-t 在附加容器或容器已经在运行时,使用此超时时间(以秒为单位)来关闭容器,默认为10秒。

2、down

​ 停止容器并删除 up 创建的容器、网络和镜像。

默认情况下,删除的东西只有:

  • 用于在 Compose 文件中定义的服务的容器。
  • 在 Compose 文件的 Networks 部分中定义的网络。
  • 默认网络(如果使用了一个网络)

​ 注意:定义为外部的网络和卷永远不会被删除。默认情况下,不删除匿名卷。然而,由于它们没有一个稳定的名称,它们不会被后续的up自动挂载。对于需要在更新之间持久保存的数据,使用显式路径作为绑定挂载或命名卷。

1
2
# 语法
docker compose down [OPTIONS]

Options

选项 描述
–remove-orphans 删除未在 Compose 文件中定义的服务的容器。
–rmi 删除服务使用的镜像。"local"只删除没有自定义标签的图片(“local”、“all”)
–timeout,-t 指定以秒为单位的关机超时时间,默认为 10 秒。
–volumes,-v 删除在 Compose 文件的 volumes 部分声明的命名卷和附加到容器的匿名卷。

3、build

用于构建或重新构建服务

1
2
# 语法
docker compose build [OPTIONS] [SERVICE...]

Options

选项 描述
–build-arg 为服务设置构建时变量。
–memory,-m 为构建容器设置内存限制。
–no-cache 在构建镜像时不使用缓存。
–progress 设置进度输出类型(auto,tty, plain, quiet),默认为 auto。
–pull 总是尝试拉出镜像的新版本。
–quiet,-q 不要向STDOUT打印任何内容。
–ssh 设置构建服务镜像时使用的SSH身份验证。(使用默认的SSH代理时使用’default’)

4、ps

列出Compose项目的容器,以及当前状态和公开的端口。默认情况下,运行和停止的容器都显示出来。

1
2
# 语法
docker compose ps [OPTIONS] [SERVICE...]

Options

选项 描述
–all,-a 显示所有已停止的容器(包括由run命令创建的容器)
–filter 通过属性过滤服务,例如 status
–format 格式化输出,可选格式:pretty 、 json
–quiet,-q 只显示 id
–services 显示服务
–status 按状态过滤服务,可选状态:paused、restarting、removing、running、dead、created、exited

5、exec

在运行的容器中执行命令。这相当于针对 Compose 服务的 docker exec。通过这个子命令,您可以在服务中运行任意命令。默认情况下,命令会分配TTY,因此可以使用 docker compose exec web sh 等命令来获得交互式提示。

1
2
# 语法
docker compose exec [OPTIONS] SERVICE COMMAND [ARGS...]

Options

选项 描述
–detach,-d 分离模式,运行命令在后端。
–env,-e 设置环境变量。
–index 如果一个服务有多个实例,则使用容器的索引,默认值为 1
–interactive,-i 保持STDIN打开,即使没有连接,默认值为 true
–user,-u 以该用户运行该命令。
–workdir,-w 此命令的 workdir 目录路径。

6、top

显示正在运行的进程。

1
2
# 语法
docker compose top [SERVICES...]

示例:

1
2
3
4
5
6
7
8
9
[root@localhost test]# docker compose top
test-kong-1
UID PID PPID C STIME TTY TIME CMD
100 2326 2251 2 05:51 ? 00:00:04 nginx: master process
100 3721 2326 0 05:52 ? 00:00:00 nginx: worker process
100 3722 2326 0 05:52 ? 00:00:00 nginx: worker process
100 3723 2326 0 05:52 ? 00:00:00 nginx: worker process
100 3724 2326 0 05:52 ? 00:00:00 nginx: worker process

7、logs

查看容器的日志输出。

1
2
# 语法
docker compose logs [OPTIONS] [SERVICE...]

Options

选项 描述
–follow,-f 跟踪日志输出。
–no-color 使用单色输出。
–no-log-prefix 不打印日志前缀。
–since 显示自时间戳以来的日志,示例: (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
–tail 从每个容器的日志末尾开始显示的行数。默认需要跟参数 all 。
–timestamps,-t 显示时间戳。
–until 显示自时间戳之前的日志,示例: (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

8、pause、unpause

暂停/取消暂停正在运行的服务容器。

1
2
3
4
5
# 暂停语法
docker compose pause [SERVICE...]

# 取消暂停语法
docker compose unpause [SERVICE...]

9、rm

移除停止的服务容器

1
2
# 语法
docker compose rm [OPTIONS] [SERVICE...]

Options

选项 描述
–force,-f 不要询问是否要移除。
–stop,-s 删除容器之前停止容器。
–volumes,-v 删除连接到容器的所有匿名卷。

10、start、stop、restart

开始、停止、重启服务

1
2
3
4
5
6
7
8
# 开始服务
docker compose start [SERVICE...]

# 停止服务
docker compose stop [SERVICE...]

# 重启服务
docker compose restart [SERVICE...]

11、ls

列出正在运行的容器项目

1
2
# 语法
docker compose ls [OPTIONS]

Options

选项 描述
–all,-a 显示全部的 compose 项目。
–filter 根据提供的条件筛选输出。
–format 格式化输出,可选格式:pretty、json,默认为pretty。
–quiet,-q 只显示 id。

12、version

显示Docker Compose版本信息

1
docker compose version [OPTIONS]

Options

选项 描述
–format,-f 格式化输出,可选格式:pretty、json,默认为pretty。
–short 只显示Compose的版本号。

示例:

1
2
[root@localhost ~]# docker compose version
Docker Compose version v2.10.2

参考文献

1️⃣Overview | Docker Documentation

2️⃣Docker Compose - Docker — 从入门到实践 (gitbook.io)

3️⃣Overview of docker compose CLI | Docker Documentation

4️⃣Install on Linux | Docker Documentation