6Docker 深度探索

Docker Compose

多容器应用

Docker Compose编排服务

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第6章:Docker Compose(Multi-Container Applications)

一、导读

1.1 本章学习目标

真实应用由多个服务组成。Docker Compose 用一个 YAML 文件定义多容器应用,一条命令启动所有服务。

本章的核心学习目标包括:

  • 掌握 Compose 文件结构:services、networks、volumes。
  • 配置服务间通信:DNS 解析、依赖关系。
  • 管理数据持久化:Volume 配置。
  • 控制启动顺序:depends_on 和健康检查。

1.2 为什么本章如此重要

现代应用通常包含 Web 服务器、数据库、缓存、消息队列等多个服务。手动管理这些服务的启动、网络、存储是极其繁琐的。Docker Compose 让你用声明式的方式定义整个应用栈。

1.3 核心问题引导

Compose 文件中 services、networks、volumes 的关系是什么?

服务间如何通过 DNS 互相访问?

depends_on 会等待服务就绪吗?如何确保依赖服务真正可用?

如何在 Compose 中配置健康检查?


二、核心概念详解

2.1 Compose 文件结构

yaml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/myapp

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 5s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7-alpine

volumes:
  pgdata:

2.2 服务间通信

Compose 自动创建网络,服务名就是 DNS 主机名:

yaml
services:
  web:
    environment:
      - DB_HOST=db      # 直接用服务名
      - REDIS_HOST=cache
bash
# 在 web 容器中
curl http://db:5432    # 直接访问数据库
curl http://cache:6379  # 直接访问缓存

2.3 depends_on

yaml
services:
  web:
    depends_on:
      db:
        condition: service_healthy    # 等待健康检查通过
      cache:
        condition: service_started    # 等待启动(不等待就绪)

注意:depends_on 只控制启动顺序,不等待服务真正就绪(除非使用 condition: service_healthy)。

2.4 常用命令

bash
docker compose up -d              # 后台启动
docker compose down               # 停止并删除
docker compose logs -f web        # 查看日志
docker compose ps                 # 查看状态
docker compose exec web bash      # 进入容器
docker compose build --no-cache   # 重新构建
docker compose up --scale web=3   # 扩展副本

三、实战案例

3.1 完整的 Web 应用栈

yaml
version: '3.8'

services:
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend

  backend:
    build: ./backend
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/myapp
      - REDIS_URL=redis://cache:6379
      - KAFKA_BROKERS=kafka:9092
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    volumes:
      - ./backend:/app
      - /app/node_modules

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  kafka:
    image: confluentinc/cp-kafka:7.4.0
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    ports:
      - "9092:9092"

volumes:
  pgdata:

四、本章小结

Compose 文件定义 services、networks、volumes。

服务间通过 DNS 通信,服务名就是主机名。

depends_on 控制启动顺序,配合健康检查等待就绪。

常用命令:up、down、logs、exec、scale。


五、思考与练习

思考题

Compose 创建的网络和默认 bridge 网络有什么区别?

如果数据库启动很慢,depends_on 能保证应用连接时数据库已就绪吗?

如何在 Compose 中实现服务的热重载?

练习题

编写 docker-compose.yml 包含 Web、数据库、缓存、消息队列。

配置健康检查和依赖关系。

练习启动、停止、查看日志、进入容器调试。

6/8Dock
0%