1. 概述
在使用 Docker 的过程中,如果同时管理多个容器,很快就会变得繁琐复杂。
Docker Compose 是一个帮助我们解决这个问题的工具,它能让我们轻松地一次性管理多个容器。
在本教程中,我们将介绍 Docker Compose 的核心功能及其强大的机制。
2. YAML 配置详解
Docker Compose 的工作原理是基于一个名为 docker-compose.yml
的配置文件。这个 YAML 格式的文件集中定义了多个服务、卷(volumes)和网络(networks)等规则。
YAML 是一种既易于人阅读,又便于机器解析的格式,非常适合用于快速描述整个项目的结构。
几乎每一个配置项都对应于一个 Docker 命令。这意味着我们只需要运行:
docker-compose up
就能自动完成多个容器的创建、网络配置、卷挂载等复杂操作,省去了手动编写脚本的麻烦。
基本结构如下:
version: "3.7"
services:
...
volumes:
...
networks:
...
接下来我们分别看看这些核心元素的作用。
2.1. 服务(Services)
服务(Service)是 Docker Compose 中的核心概念,它定义了容器的运行时配置。
比如一个典型的 Web 应用可能包括前端、后端和数据库三个组件,我们可以将它们分别定义为三个服务:
services:
frontend:
image: my-vue-app
backend:
image: my-springboot-app
db:
image: postgres
每个服务可以配置镜像、端口映射、卷挂载、依赖关系等。
2.2. 卷(Volumes)与网络(Networks)
卷(Volume)用于在主机与容器之间共享数据,也可以用于多个容器之间共享数据。可以理解为容器可见的“共享目录”。
网络(Network)定义了容器之间的通信规则。公共网络中的容器可以互相访问,私有网络则起到了隔离作用。
我们将在下文详细讨论这些配置。
3. 服务配置详解
下面我们将深入探讨服务的常用配置项。
3.1. 使用现有镜像
如果你的服务所需的镜像已经在 Docker Hub 或其他仓库中存在,可以使用 image
指定镜像名称和标签:
services:
my-service:
image: ubuntu:latest
3.2. 构建自定义镜像
如果需要从源码构建镜像,使用 build
指定 Dockerfile 的路径:
services:
my-custom-app:
build: /path/to/dockerfile/
也可以直接使用 Git 仓库地址:
services:
my-custom-app:
build: https://github.com/my-company/my-project.git
如果同时指定 image
,则构建后的镜像会使用这个名称:
services:
my-custom-app:
build: https://github.com/my-company/my-project.git
image: my-project-image
3.3. 网络配置
Docker 容器之间的通信依赖于网络。服务可以通过服务名和端口互相访问,前提是该端口已通过 expose
暴露:
services:
network-example-service:
image: karthequian/helloworld:latest
expose:
- "80"
如果希望从宿主机访问容器服务,则需要使用 ports
显式映射端口:
services:
network-example-service:
image: karthequian/helloworld:latest
ports:
- "80:80"
也可以映射不同的端口号:
services:
my-custom-app:
image: myapp:latest
ports:
- "8080:3000"
还可以定义多个网络,实现容器隔离:
services:
network-example-service:
image: karthequian/helloworld:latest
networks:
- my-shared-network
networks:
my-shared-network: {}
3.4. 卷配置
Docker 支持三种类型的卷:匿名卷、命名卷和主机卷。
- 匿名卷:由 Docker 自动生成,生命周期与容器绑定。
- 命名卷:推荐使用,由 Docker 管理,生命周期独立于容器。
- 主机卷:将宿主机目录挂载到容器中。
示例:
services:
volumes-example-service:
image: alpine:latest
volumes:
- my-named-global-volume:/my-volumes/named-global-volume
- /tmp:/my-volumes/host-volume
- /home:/my-volumes/readonly-host-volume:ro
volumes:
my-named-global-volume:
其中:
my-named-global-volume
是命名卷,多个服务可以共享。/tmp
是主机卷,容器可读写。/home
以只读方式挂载(通过:ro
)。
3.5. 服务依赖关系
通过 depends_on
可以定义服务之间的启动顺序:
services:
kafka:
image: wurstmeister/kafka:2.11-0.11.0.3
depends_on:
- zookeeper
zookeeper:
image: wurstmeister/zookeeper
⚠️ 注意:depends_on
仅保证依赖服务已启动,不保证其完全就绪。如需精确控制启动顺序,需结合健康检查或脚本。
4. 环境变量管理
Docker Compose 支持环境变量配置,可以在 environment
中定义:
services:
database:
image: "postgres:${POSTGRES_VERSION}"
environment:
DB: mydb
USER: "${USER}"
变量值可以通过以下方式提供:
.env
文件:
POSTGRES_VERSION=alpine
USER=foo
- 命令行导出:
export POSTGRES_VERSION=alpine
export USER=foo
docker-compose up
- 一行命令指定:
POSTGRES_VERSION=alpine USER=foo docker-compose up
还可以为变量设置默认值:
environment:
DB: mydb
USER: "${USER:-admin}"
如果 USER
未设置或为空,则使用 admin
。如果希望允许空值传入,使用:
USER: "${USER-admin}"
5. 扩展与副本
旧版本中使用 docker-compose scale
扩展服务实例,新版本已改为使用 --scale
参数,并结合 Docker Swarm 实现。
例如:
services:
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 6
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
⚠️ 注意:deploy
配置仅在使用 Docker Swarm 模式时生效。
6. 实战案例:Spring Cloud Data Flow
理论讲得再多,不如实战来得直观。Spring Cloud Data Flow 是一个典型使用 Docker Compose 的项目。
你可以下载其官方 YAML 文件并运行:
DATAFLOW_VERSION=2.1.0.RELEASE SKIPPER_VERSION=2.0.2.RELEASE docker-compose up
Docker Compose 会自动下载、配置并启动所有组件,并将日志统一输出到当前终端,每个容器日志还会以不同颜色区分,提升可读性:
常见错误:
lookup registry-1.docker.io: no such host
✅ 解决方案之一是设置 DNS 为 8.8.8.8
。
7. 生命周期管理
Docker Compose 提供了完整的生命周期管理命令。
7.1. 启动服务
启动所有服务(首次运行):
docker-compose up
以后可以直接启动:
docker-compose start
指定非默认配置文件:
docker-compose -f custom-compose-file.yml start
后台运行:
docker-compose up -d
7.2. 停止服务
停止服务(保留数据):
docker-compose stop
重置环境(删除容器、网络,但保留外部卷):
docker-compose down
8. 总结
Docker Compose 是管理多容器应用的利器。通过一个 YAML 文件,我们可以定义服务、网络、卷、环境变量、依赖关系等复杂配置,极大简化了 Docker 的使用成本。
如需查看完整 docker-compose.yml
示例文件,可访问我们的 GitHub 仓库:
源码地址:GitHub 示例仓库