Skip to content

写给懒猫微服玩家的容器小书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

小李的项目结构如下:

myapp/
├── backend/      # Flask 应用
│   ├── app.py
│   └── Dockerfile
├── frontend/     # 静态页面
│   ├── index.html
│   └── Dockerfile
└── docker-compose.yml

docker-compose.yml 示例:

yaml
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 命令实战速查

小李在项目目录下运行:

bash
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:)会自动创建、管理。

支持:

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

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

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

.env 文件:

env
DB_PASSWORD=123456
DB_NAME=mydb

Compose 文件中使用方式:

yaml
environment:
  - MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
  - MYSQL_DATABASE=${DB_NAME}

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


🧬 第六节:高级配置技巧

1. 统一重启策略:

yaml
restart: unless-stopped

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


2. 多阶段构建支持:

yaml
build:
  context: ./backend
  dockerfile: Dockerfile.prod

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


3. Healthcheck 健康检查:

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

🆚 第七节:Docker Compose vs Kubernetes 简析

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

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


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

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

.gitlab-ci.yml 示例:

yaml
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 并与主文件合并。

文件结构:

docker-compose.yml
docker-compose.override.yml
.env.dev
.env.prod

主配置(docker-compose.yml):

yaml
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - ENV_MODE=${MODE}

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

yaml
services:
  web:
    volumes:
      - ./src:/app/src
    environment:
      - DEBUG=true

运行:

bash
MODE=development docker-compose up

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

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

示例:

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

运行:

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

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

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


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

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

老周摇头说:

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


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

比如 Flask 等数据库:

bash
#!/bin/bash
until nc -z db 3306; do
  echo "Waiting for db..."
  sleep 1
done

python app.py

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

dockerfile
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 updocker 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 简化版本。”


对照表:

ComposeKubernetes
services:Deployment + Pod
volumes:PersistentVolumeClaim
ports:Service(NodePort / ClusterIP)
depends_on:initContainers 或 readinessProbe
.envConfigMap / Secret
docker-compose.ymlHelm Chart (values.yaml + templates)

示例:Compose 转 Helm 构思

Compose 配置:

yaml
services:
  web:
    image: myapp:latest
    ports:
      - "8080:80"
    environment:
      - DEBUG=true

Helm values.yaml

yaml
image:
  repository: myapp
  tag: latest

env:
  - name: DEBUG
    value: "true"

service:
  port: 8080
  targetPort: 80

Helm deployment.yaml(模板):

yaml
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 才是真正的大型音乐厅。但有了排练,登台才不会慌。”

❤️喜欢