Docker_03_DockerCompose多容器编排

Docker Compose 多容器编排:从入门到实战

一、什么是 Docker Compose?

1.1 定义

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 YAML 文件配置应用的服务、网络和卷,然后使用一个命令就可以创建和启动所有服务。

1.2 为什么需要 Compose?

没有 Compose 时,启动一个 Web 应用需要:

bash 复制代码
docker network create myapp
docker volume create db-data
docker run -d --network myapp --name db -v db-data:/var/lib/mysql mysql:8.0
docker run -d --network myapp --name redis redis:alpine
docker run -d --network myapp -p 8080:8080 --depends-on db,redis myapp:latest

使用 Compose 后,一个文件搞定:

yaml 复制代码
services:
  db:
    image: mysql:8.0
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - myapp
  redis:
    image: redis:alpine
    networks:
      - myapp
  app:
    build: .
    ports:
      - "8080:8080"
    depends_on:
      - db
      - redis
    networks:
      - myapp

volumes:
  db-data:

networks:
  myapp:

1.3 核心概念

  • Service:一个服务对应一个容器
  • Project:一组关联的服务,由一个 compose 文件定义
  • Compose File:YAML 格式,定义服务、网络、卷等配置

二、安装与基础

2.1 安装

Docker Compose 已集成到 Docker 中(Docker Compose V2)。安装 Docker 时自动包含。

bash 复制代码
# 验证安装
docker compose version
# 输出: Docker Compose version v2.x.x

# 旧版本(独立安装)
docker-compose version

2.2 基本使用流程

bash 复制代码
# 1. 编写 docker-compose.yml
# 2. 启动所有服务
docker compose up

# 后台运行
docker compose up -d

# 3. 查看服务状态
docker compose ps

# 4. 查看日志
docker compose logs
docker compose logs -f  # 实时跟踪

# 5. 停止并删除所有服务
docker compose down

# 6. 停止服务(不删除)
docker compose stop

# 7. 重启服务
docker compose restart

三、docker-compose.yml 详解

3.1 基本结构

yaml 复制代码
services:    # 定义服务
  service-name:
    image: ...
    build: ...
    ports: ...
    ...

volumes:     # 定义数据卷
  volume-name:

networks:    # 定义网络
  network-name:

configs:     # 定义配置
secrets:     # 定义密钥

3.2 服务配置项

镜像与构建
yaml 复制代码
services:
  web:
    # 方式一:使用现有镜像
    image: nginx:latest
    
    # 方式二:从 Dockerfile 构建
    build:
      context: ./app        # 构建上下文
      dockerfile: Dockerfile  # Dockerfile 路径
      args:                   # 构建参数
        VERSION: "1.0"
端口映射
yaml 复制代码
services:
  web:
    image: nginx
    ports:
      - "8080:80"      # 宿主机:容器
      - "8443:443"
      - "127.0.0.1:9090:80"  # 绑定特定 IP
环境变量
yaml 复制代码
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: testdb
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    env_file:
      - .env  # 从文件加载
数据卷
yaml 复制代码
services:
  db:
    image: mysql:8.0
    volumes:
      - db-data:/var/lib/mysql          # 命名卷
      - ./config:/etc/mysql/conf.d      # 绑定挂载
      - type: bind
        source: ./logs
        target: /var/log/mysql
        read_only: true

volumes:
  db-data:  # 声明命名卷
网络配置
yaml 复制代码
services:
  web:
    image: nginx
    networks:
      - frontend
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
依赖管理
yaml 复制代码
services:
  web:
    image: myapp
    depends_on:
      - db
      - redis
  
  db:
    image: mysql:8.0
    
  redis:
    image: redis:alpine

注意 :depends_on 只控制启动顺序,不等待服务就绪。可以使用健康检查:

yaml 复制代码
services:
  web:
    image: myapp
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
资源限制
yaml 复制代码
services:
  web:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
重启策略
yaml 复制代码
services:
  web:
    image: myapp
    restart: always        # 总是重启
    # restart: on-failure  # 失败时重启
    # restart: unless-stopped  # 除非手动停止
命令覆盖
yaml 复制代码
services:
  web:
    image: nginx
    command: nginx -g "daemon off;"
    entrypoint: ["/docker-entrypoint.sh"]

四、常用命令

4.1 服务管理

bash 复制代码
# 启动所有服务
docker compose up -d

# 启动指定服务
docker compose up -d web db

# 停止所有服务
docker compose stop

# 停止并删除容器、网络
docker compose down

# 停止并删除容器、网络、卷
docker compose down -v

# 重启服务
docker compose restart

# 暂停服务
docker compose pause

# 恢复暂停的服务
docker compose unpause

4.2 查看状态

bash 复制代码
# 查看服务状态
docker compose ps

# 查看日志
docker compose logs
docker compose logs -f
docker compose logs web  # 指定服务

# 查看服务进程
docker compose top

# 查看资源使用
docker compose stats

4.3 进入容器

bash 复制代码
# 在运行中的服务执行命令
docker compose exec web bash
docker compose exec db mysql -uroot -p

# 列出服务
docker compose ps --services

4.4 构建与更新

bash 复制代码
# 构建镜像
docker compose build

# 构建并启动
docker compose up -d --build

# 更新镜像并重启
docker compose pull
docker compose up -d

# 不使用缓存重新构建
docker compose build --no-cache

4.5 扩缩容

bash 复制代码
# 扩展服务副本数
docker compose up -d --scale web=3

# 查看副本状态
docker compose ps

五、实战示例

5.1 Spring Boot + MySQL + Redis

yaml 复制代码
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/zoodb
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: root123
      SPRING_REDIS_HOST: redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - backend
    restart: unless-stopped

  db:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: zoodb
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend
    restart: unless-stopped

volumes:
  mysql-data:
  redis-data:

networks:
  backend:
    driver: bridge

5.2 WordPress + MySQL

yaml 复制代码
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: wp_pass
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress-data:/var/www/html
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: wp_pass
      MYSQL_ROOT_PASSWORD: root_pass
    volumes:
      - db-data:/var/lib/mysql
    restart: unless-stopped

volumes:
  wordpress-data:
  db-data:

5.3 Nginx 反向代理 + 多服务

yaml 复制代码
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - app1
      - app2
    networks:
      - frontend

  app1:
    image: myapp1:latest
    networks:
      - frontend
      - backend

  app2:
    image: myapp2:latest
    networks:
      - frontend
      - backend

  db:
    image: mysql:8.0
    networks:
      - backend

networks:
  frontend:
  backend:

六、环境变量与 .env 文件

6.1 使用 .env 文件

bash 复制代码
# .env 文件
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=zoodb
APP_PORT=8080
yaml 复制代码
# docker-compose.yml
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}

6.2 变量优先级

  1. 命令行 -e 参数
  2. Shell 环境变量
  3. .env 文件
  4. docker-compose.yml 中的 environment

七、最佳实践

7.1 安全建议

  • 不要在 compose 文件中硬编码密码,使用 .env 文件或 secrets
  • 限制端口暴露范围,使用 127.0.0.1:port:port
  • 使用健康检查确保服务就绪
  • 定期更新镜像版本

7.2 性能优化

  • 使用命名卷而非绑定挂载
  • 合理设置资源限制
  • 使用 Alpine 镜像减小体积
  • 利用构建缓存

7.3 目录结构建议

复制代码
project/
├── docker-compose.yml
├── .env
├── app/
│   ├── Dockerfile
│   └── src/
├── nginx/
│   └── nginx.conf
└── mysql/
    └── init.sql

八、面试高频题

Q1:docker-compose 中的 depends_on 有什么作用?有什么局限?

A:depends_on 控制服务的启动顺序,确保依赖的服务先启动。但局限是它只等待容器启动,不等待服务就绪。例如 MySQL 容器启动了但还没准备好接受连接。解决方案是使用健康检查配合 condition: service_healthy。

Q2:Compose 文件中如何管理多个环境(开发、测试、生产)?

A:可以使用多个 compose 文件叠加。基础文件 docker-compose.yml 定义通用配置,环境文件如 docker-compose.prod.yml 覆盖特定配置。使用 docker compose -f docker-compose.yml -f docker-compose.prod.yml up 启动。也可以用 .env 文件和环境变量区分。

Q3:如何在 Compose 中实现服务间的负载均衡?

A:使用 scale 参数扩展服务副本:docker compose up -d --scale web=3。然后在 Nginx 等反向代理中配置上游服务器列表。也可以使用 Docker Swarm 的内置负载均衡。


至此,Docker 系列三篇博客全部完成!🎉

相关推荐
shdkfbbv1 小时前
【无标题】
linux·运维·服务器
ESDWAN3 小时前
SD-WAN 企业选型与落地指南:从链路测试到网络架构设计
运维·网络·架构
啊哈一半醒3 小时前
Docker 底层知识:从 Namespace 到 UnionFS
运维·docker·容器
_smart_boy__3 小时前
I.MX6U开发板Uboot无法ping Ubuntu问题解决方案(二)
linux·运维·ubuntu
~光~~3 小时前
【嵌入式Linux学习】GFP_NOIO / GFP_NOFS(Linux 内核 gfp 分配标志)
linux·运维·学习
涵美女程序猿3 小时前
ChatCut online 剪负载均衡健康检查演练录屏:后端池、探针路径与摘除阈值怎样对应
运维·程序人生·电脑·负载均衡
分布式存储与RustFS3 小时前
升级 RustFS 二进制不停机:一条一条换,留一条退路
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
吴声子夜歌4 小时前
Nginx应用与运维——Nginx核心配置指令(一)
运维·nginx
android阿杜4 小时前
Ubuntu 26.04 LTS 系统每次重启后屏幕亮度都会增加一点
linux·运维·ubuntu