写给懒猫微服玩家的容器小书Docker篇(五):《多容器交响曲:Docker Compose 上场》

一直想写一本容器小书,真好懒猫基本都做了容器化,所以把这部分分享出来。不同的是,懒猫微服中使用 pg-docker 来替代 docker 命令,使用 dockge 来执行 docker-compose。以下讲解以标准 docker 为主,这样子既学会了 docker 知识,也能够在懒猫微服上启动 Docker 服务。

《多容器交响曲:Docker Compose 上场》讲的是使用 Docker Compose 统一编排多容器服务,理解 YAML 配置结构、服务依赖、网络、挂载、构建策略、变量管理、Compose vs K8s 初探等


🎼 开篇:服务之间的管弦乐团

随着项目日益复杂,小李的服务已经不再是一个容器就能承载的了。

前端、后端、数据库、缓存、日志系统……像一个交响乐团,需要统一调度、和谐配合。

老周递给他一个新的工具:“Docker Compose——它是你的指挥棒。”


🎻 第一节:什么是 Docker Compose?

老周解释:

“Docker Compose 是 Docker 的多容器编排工具,用一份 docker-compose.yml 文件,就能同时启动、停止、构建多个服务。”

Compose 帮你解决:

  • 多个服务启动顺序
  • 多容器共享网络
  • 统一管理环境变量
  • 配置简洁、开发者友好
  • 跨平台部署一致

📄 第二节:写出你的第一个 docker-compose.yml

小李的项目结构如下:

1
2
3
4
5
6
7
8
myapp/
├── backend/ # Flask 应用
│ ├── app.py
│ └── Dockerfile
├── frontend/ # 静态页面
│ ├── index.html
│ └── Dockerfile
└── docker-compose.yml

docker-compose.yml 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: "3.9"

services:
backend:
build: ./backend
ports:
- "5000:5000"
volumes:
- ./backend:/app
environment:
- DB_HOST=db
depends_on:
- db

frontend:
build: ./frontend
ports:
- "3000:80"

db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=mydb
volumes:
- dbdata:/var/lib/mysql

volumes:
dbdata:

🔧 每个 service 就是一个容器定义,Compose 会为它们创建默认网络,自动 DNS 互通。


🧪 第三节:Compose 命令实战速查

小李在项目目录下运行:

1
docker-compose up -d

后台启动所有服务!

其他常用命令:

操作 命令
构建镜像 docker-compose build
后台启动 docker-compose up -d
前台启动 + 日志输出 docker-compose up
停止服务 docker-compose down
查看容器日志 docker-compose logs [服务名]
重启某个服务 docker-compose restart 服务名
进入某个容器 docker-compose exec 服务名 bash

📦 第四节:Compose 的网络与数据共享机制

老周介绍:

“Compose 默认创建一个网络,所有服务能通过服务名互相访问。”

在上面的例子中:

  • backend 容器可以用 db:3306 连接 MySQL
  • frontend 可通过 backend:5000 访问后端 API

小李不再需要手动 docker network create--network 参数,Compose 一切自动打通。

Volume 的挂载:

Compose 中的 volume 显式声明(如 dbdata:)会自动创建、管理。

支持:

1
2
3
4
volumes:
- ./data:/data # Bind mount
- myvolume:/data # Named volume
- /custom/path:/data:ro # 带权限控制

🌐 第五节:使用 .env 管理配置变量

Compose 支持使用 .env 文件集中管理变量:

.env 文件:

1
2
DB_PASSWORD=123456
DB_NAME=mydb

Compose 文件中使用方式:

1
2
3
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
- MYSQL_DATABASE=${DB_NAME}

🚀 配合 CI/CD 时 .env 可由流水线动态生成,便于多环境切换(dev/stage/prod)。


🧬 第六节:高级配置技巧

1. 统一重启策略:

1
restart: unless-stopped

确保服务宕机时能自动重启。


2. 多阶段构建支持:

1
2
3
build:
context: ./backend
dockerfile: Dockerfile.prod

可指定构建路径、Dockerfile 文件、构建参数等。


3. Healthcheck 健康检查:

1
2
3
4
5
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3

🆚 第七节:Docker Compose vs Kubernetes 简析

特性 Compose Kubernetes
启动容器 简单 标准化
配置语言 YAML YAML
网络 自动共享 需显式配置
存储 Volume PVC + SC
服务发现 服务名互通 DNS/ClusterIP
用途 本地开发 / CI 集群部署 / 云原生
高可用 / 伸缩 ✅ 内建
社区生态 中小项目广泛使用 大型平台标准方案

小李理解了:Compose 是“轻量乐队指挥”,K8s 是“交响级 AI 指挥系统”。


🔁 第八节:Compose + CI/CD 集成发布

小李将 Compose 整合进 GitLab CI 流程:

.gitlab-ci.yml 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
services:
- docker:dind

stages:
- build
- deploy

build:
stage: build
script:
- docker-compose build

deploy:
stage: deploy
script:
- docker-compose up -d

CI 构建完镜像后,直接用 Compose 部署,既省事又稳定。


🧠 小李 Compose 使用技巧总结

目标 技巧
服务隔离 每个项目单独一个 Compose 文件
共享网络 不用写 network,服务名即 DNS
跨环境配置 使用 .env 动态切换变量
状态排查 docker-compose logs / ps / exec
多环境文件 使用 docker-compose.override.yml
CI/CD 联动 编排命令嵌入流水线任务中

🎬 尾声:指挥容器交响曲的时刻

当小李敲下 docker-compose up 的回车键,前端、后端、数据库同时启动,日志齐鸣,服务稳定运行。

“这就是我梦想的微服务协奏曲啊。”

老周拍了拍他肩膀:

“你已经能用 Compose 驾驭服务之海,下一步,是把它们部署上云、扩展弹性、自动滚动升级。”

小李点头,望向远方的集群编排系统——Kubernetes,眼中闪着新的渴望。

好!那我们就在第五章《多容器交响曲》中,继续深入补充这四大实战技能:


🧩 补充一:Compose 的多环境部署实践(开发、测试、生产)

小李希望同一套服务,在开发、测试、生产环境下分别使用不同的配置,比如:

  • 数据库密码不同
  • 是否挂载本地代码
  • 是否启用调试模式

老周教他使用 Compose 的多文件配置机制


✅ 方案一:使用 docker-compose.override.yml

Docker Compose 默认会自动加载 docker-compose.override.yml 并与主文件合并。

文件结构:

1
2
3
4
docker-compose.yml
docker-compose.override.yml
.env.dev
.env.prod

主配置(docker-compose.yml):

1
2
3
4
5
6
7
services:
web:
build: .
ports:
- "8000:8000"
environment:
- ENV_MODE=${MODE}

开发环境覆盖文件(docker-compose.override.yml):

1
2
3
4
5
6
services:
web:
volumes:
- ./src:/app/src
environment:
- DEBUG=true

运行:

1
MODE=development docker-compose up

✅ 方案二:按环境拆分多个 Compose 文件

适合 CI/CD 或部署多个 stage。

示例:

  • docker-compose.dev.yml
  • docker-compose.prod.yml

运行:

1
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

多个 -f 会按顺序合并,后面覆盖前面。

📦 建议主文件写“公共配置”,子文件按环境细化。


🎯 补充二:优化服务依赖启动顺序

小李发现,即使写了 depends_on,后端有时候也连不上数据库。

老周摇头说:

depends_on 只是控制启动顺序不是等服务就绪。数据库可能还没监听端口就已被标记为 ‘up’。”


✅ 正确姿势:服务内设置“等待就绪”

比如 Flask 等数据库:

1
2
3
4
5
6
7
#!/bin/bash
until nc -z db 3306; do
echo "Waiting for db..."
sleep 1
done

python app.py

或者使用工具包如 wait-for-it.sh

1
2
COPY wait-for-it.sh /wait-for-it.sh
ENTRYPOINT ["/wait-for-it.sh", "db:3306", "--", "python", "app.py"]

🩺 推荐结合容器健康检查,判断服务是否真正 ready。


🛠 补充三:Docker Compose V1 ➜ V2 迁移技巧

小李的 CI 工具用的是 Compose v1,项目准备升级。

老周提醒:

“Docker Compose v2 使用的是 docker compose(空格),而非 docker-compose(短横线)。”


✅ 主要变化:

项目 v1 (docker-compose) v2 (docker compose)
命令格式 docker-compose up docker compose up
安装方式 独立二进制 集成于 Docker CLI
文件格式 v2, v3 推荐统一 v3.9

✅ 迁移建议:

  • 删除旧的 docker-compose 二进制
  • 使用 docker compose CLI
  • 更新脚本、CI 工具调用方式
  • 移除 legacy 字段(如 links
  • 检查 .env 是否兼容(v2 更严格)

☸️ 补充四:Compose 与 Helm 的映射关系对照

当小李进入 Kubernetes 世界,他问老周:

“Compose 文件和 K8s 的 YAML 有啥对应关系?”

老周说:“很好理解,Compose 是开发者的 K8s 简化版本。”


对照表:

Compose Kubernetes
services: Deployment + Pod
volumes: PersistentVolumeClaim
ports: Service(NodePort / ClusterIP)
depends_on: initContainers 或 readinessProbe
.env ConfigMap / Secret
docker-compose.yml Helm Chart (values.yaml + templates)

示例:Compose 转 Helm 构思

Compose 配置:

1
2
3
4
5
6
7
services:
web:
image: myapp:latest
ports:
- "8080:80"
environment:
- DEBUG=true

Helm values.yaml

1
2
3
4
5
6
7
8
9
10
11
image:
repository: myapp
tag: latest

env:
- name: DEBUG
value: "true"

service:
port: 8080
targetPort: 80

Helm deployment.yaml(模板):

1
2
3
4
5
6
7
8
containers:
- name: web
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value }}
{{- end }}

✅ 小李意识到,Helm 是“模板化 + 分层管理”的 Compose 超集,是云原生部署的标准组件管理器。


🎬 尾声:Compose 是微服务上云的跳板

小李已经用 Docker Compose 实现了:

  • 开发环境热更新
  • 测试环境集成数据库
  • 生产环境独立配置
  • CI/CD 自动部署服务
  • 为 Kubernetes 迁移打下基础

他明白了:

“Compose 就像舞台排练,Kubernetes 才是真正的大型音乐厅。但有了排练,登台才不会慌。”

写给懒猫微服玩家的容器小书Docker篇(五):《多容器交响曲:Docker Compose 上场》

https://xu-hardy.github.io/写给懒猫微服玩家的容器小书docker篇(五):《多容器交响曲:docker-compose-上场》/

作者

Xu

发布于

2025-07-02

更新于

2025-07-01

许可协议

评论