本节摘要:Compose 是单机多容器应用的声明式管理工具——一份 YAML 文件定义全部服务、网络与卷,两条命令完成起航与收港。本节讲清它的定位与边界:什么场景该上、什么场景不该上。
先量化痛点。复盘第 5 章手工组队那支 Web 加数据库的小船队,把动作列成清单:建网络一条、起数据库一条(五个参数)、起应用一条(四个参数)、验证互联一条——五条命令、九个参数、一个必须人工保证的起吊顺序。这还只是两只箱子;微服务动辄六七只,手工清单的长度和出错概率同步爆炸。
Compose 的做法是把这些动作全部翻译成事实陈述。看一眼它的长相(细节下一节讲,此处找感觉):
# 声明文件(惯例名 compose.yaml):船队全部事实 services: web: image: myapp:0.1 ports: - "8080:8000" environment: - DB_HOST=db depends_on: db: condition: service_healthy db: image: redis:7-alpine volumes: - cache-data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s volumes: cache-data:
# 然后整个编队就是两条命令的事 docker compose up -d # 起航:缺什么建什么,顺序自动排 docker compose down # 收港:编队全体送离,网络一并清理
九个手工参数变成十五行声明,而换台机器的重建成本从"翻文档祈祷"变成"拷一个文件、敲一条命令"。可复制性是 Compose 带来的质变:开发环境、测试环境、演示环境跑的是字面意义上同一份文件。
Compose 不是万金油,三个标准帮你快速判断。
标准一:单机还是跨机。 Compose 管一台宿主机上的编队;需要跨多台机器调度、自动容错、滚动扩缩的场景,那是编排平台(Swarm、Kubernetes)的领地。判断诀窍:如果你的可靠性要求超出"这台机器不能坏",该看第 7.5 节了。
标准二:服务的形态。 Web 应用加数据库加缓存加队列,典型 Compose 场景;本地开发环境的全家桶(应用加依赖的中间件)更是 Compose 的招牌用法。反之,单个无状态小工具,直接 run 更简单,别为了用工具而上文件。
标准三:谁要懂它。 Compose 文件会被提交进代码库,团队所有人(包括不碰运维的开发)都能读懂、能改、能起同一套环境——这个协作红利在"只有运维一个人会配"的环境里不存在。如果环境配置永远只有一个人看得懂,先解决协作问题。
把边界说透,免得学到后面犯迷糊。Compose 与 Kubernetes 们解决的是不同量级的问题:
| 维度 | Compose | 编排平台(如 K8s) |
|---|---|---|
| 管理范围 | 单台宿主机 | 跨机器集群 |
| 声明文件 | 简洁,分钟上手 | 完善,学习曲线陡 |
| 故障自愈 | 重启策略(单机内) | 集群级调度与迁移 |
| 适用阶段 | 开发、测试、小型生产 | 中大型生产 |
| 上手成本 | 一杯咖啡的时间 | 以周计 |
新手常见的问题是"要不要跳过 Compose 直接学编排"。我的建议是反过来的:先 Compose 后编排。声明式思维、服务互联、健康检查、环境配置——这些概念在 Compose 里以最低的成本出现,学透之后上编排平台只剩语法学习,而不是概念加语法双倍暴击。Compose 文件与编排平台的资源配置也有官方的转换工具,这条升级路是修好的。
空谈不如手感。给一个三十秒的最小体验——单服务编队,感受 up 与 down 的编队语义:
# 随便建个工作目录,写一份最小声明 mkdir fleet-hello && cd fleet-hello # 声明文件内容(compose.yaml): # services: # hello: # image: nginx:1.25-alpine # ports: # - "8090:80" # 起航:注意看输出——引擎建了网络、起了容器,一气呵成 docker compose up -d # [+] Running 2/2 # Network fleet-hello_default Created # Container fleet-hello-hello-1 Started # 瞭望:编队视角的状态列表(服务名而非容器名) docker compose ps # NAME STATUS PORTS # fleet-hello-hello-1 Up 5 seconds 0.0.0.0:8090->80/tcp # 收港:连网络带容器一次清干净 docker compose down # [+] Running 2/2 # Container fleet-hello-hello-1 Removed # Network fleet-hello_default Removed
注意到输出里的细节了吗——引擎自动建了一条编队专属网络(fleet-hello_default),收港时连网络一起收走。第 5 章手工做的那些事,编队模式替你记着呢。
关于工具本身,两个版本信息帮你对齐认知:Compose 早期是独立的 docker-compose 命令(Python 实现),后来重写为引擎插件形态(Go 实现),如今随 Docker Desktop 与新版引擎默认自带,命令写作 docker compose(空格)。老教程与环境里遇到的 docker-compose(连字符)是旧形态,功能对应、参数略有出入——本文一律用插件形态的写法。判断自己环境里有没有,一条命令的事:
# 确认插件形态可用(有版本号输出即可开练) docker compose version # Docker Compose version v2.29.7
输出的版本号以 v2 开头,就是插件形态;若提示命令不存在,回 2.1 节核对你机器上的安装来源与引擎版本——桌面版安装通常已自带,服务器版偶需补装插件包。
下一节进入核心手艺站:声明文件的完整写法。