Docker_Compose基础

一、Docker Compose概述

1.1 Compose简介

1.1.1 什么是Docker Compose

定义:

Docker Compose = 多容器应用编排工具
就像: 指挥家指挥整个乐队演奏

核心功能:
├─ 定义多容器应用架构
├─ 一键启动/停止应用
├─ 管理服务依赖关系
├─ 配置网络和数据卷
└─ 环境变量管理

应用场景:
├─ 开发环境快速搭建
├─ 自动化测试环境
├─ CI/CD流水线
└─ 单机部署应用

东巴文理解:

传统方式部署多容器应用:
├─ 手动创建网络
├─ 手动创建数据卷
├─ 手动启动多个容器
├─ 手动配置容器连接
└─ 容易出错,难以管理

使用Docker Compose:
├─ 编写docker-compose.yml文件
├─ 一键启动所有服务
├─ 自动管理依赖关系
├─ 自动配置网络和数据卷
└─ 简单高效,易于维护

1.1.2 Compose架构

架构图:

┌─────────────────────────────────────────┐
│         Docker Compose架构               │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────────────────────────────┐   │
│  │   docker-compose.yml            │   │
│  │   (应用配置文件)                 │   │
│  └──────────────┬──────────────────┘   │
│                 │                       │
│                 ↓                       │
│  ┌─────────────────────────────────┐   │
│  │   Docker Compose CLI            │   │
│  │   (命令行工具)                   │   │
│  └──────────────┬──────────────────┘   │
│                 │                       │
│                 ↓                       │
│  ┌─────────────────────────────────┐   │
│  │   Docker Engine                 │   │
│  │   (Docker引擎)                   │   │
│  └──────────────┬──────────────────┘   │
│                 │                       │
│                 ↓                       │
│  ┌─────────────────────────────────┐   │
│  │   多容器应用                     │   │
│  │   ┌──────┐ ┌──────┐ ┌──────┐   │   │
│  │   │ Web  │ │ API  │ │ DB   │   │   │
│  │   └──────┘ └──────┘ └──────┘   │   │
│  └─────────────────────────────────┘   │
└─────────────────────────────────────────┘

1.2 安装Docker Compose

1.2.1 安装方法

Linux安装:

# 下载Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose

# 验证安装
docker-compose --version

# 输出
Docker Compose version v2.20.0

Windows和macOS:

Docker Desktop for Windows和macOS
已内置Docker Compose,无需单独安装

验证:
docker-compose --version

1.2.2 Compose版本

版本说明:

Compose V1:
├─ 使用Python编写
├─ 命令: docker-compose
├─ 已停止维护
└─ 不推荐使用

Compose V2:
├─ 使用Go编写
├─ 命令: docker compose (注意空格)
├─ 性能更好
└─ 推荐使用

兼容性:
├─ V2兼容V1命令
├─ 推荐使用V2
└─ 本教程使用V2

二、Compose文件语法

2.1 基本结构

2.1.1 文件结构

docker-compose.yml:

# Compose文件版本
version: '3.8'

# 服务定义
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    networks:
      - frontend
  
  api:
    image: myapi:latest
    ports:
      - "3000:3000"
    networks:
      - frontend
      - backend
    depends_on:
      - db
  
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root123
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend

# 网络定义
networks:
  frontend:
  backend:

# 数据卷定义
volumes:
  db_data:

结构说明:

docker-compose.yml结构:
├─ version: Compose文件版本
├─ services: 服务定义(必需)
├─ networks: 网络定义(可选)
├─ volumes: 数据卷定义(可选)
├─ configs: 配置定义(可选)
└─ secrets: 密钥定义(可选)

文件要求:
├─ 使用YAML格式
├─ 缩进使用空格(不用Tab)
├─ 文件名通常为docker-compose.yml
└─ 支持环境变量替换

2.1.2 版本选择

版本对应关系:

version: '3.8'  # 推荐
├─ 支持Docker Engine 19.03.0+
├─ 支持所有特性
└─ 生产环境推荐

version: '3.0'
├─ 支持Docker Engine 1.13.0+
├─ 基本特性
└─ 兼容性好

version: '2.4'
├─ 支持Docker Engine 17.06.0+
├─ 不支持Swarm模式
└─ 单机部署

2.2 服务配置

2.2.1 基本配置

镜像配置:

services:
  # 使用已有镜像
  web:
    image: nginx:latest
  
  # 使用本地构建
  app:
    build: .
  
  # 使用指定Dockerfile
  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
  
  # 使用镜像仓库
  db:
    image: mysql:5.7

容器配置:

services:
  web:
    image: nginx:latest
    # 容器名称
    container_name: mynginx
    # 主机名
    hostname: web-server
    # 重启策略
    restart: always
    # 环境变量
    environment:
      - ENV=production
      - DEBUG=false
    # 环境变量文件
    env_file:
      - .env
      - .env.prod

2.2.2 端口配置

端口映射:

services:
  web:
    image: nginx:latest
    ports:
      # 短语法
      - "8080:80"
      - "443:443"
      # 长语法
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

端口说明:

端口映射格式:
"主机端口:容器端口"

短语法:
- "8080:80"      # 映射TCP端口
- "8080:80/tcp"  # 明确指定TCP
- "8080:80/udp"  # 映射UDP端口
- "8080-8090:80-90"  # 端口范围

长语法:
target: 容器端口
published: 主机端口
protocol: tcp/udp
mode: host(单机)/ingress(Swarm)

2.2.3 网络配置

网络连接:

services:
  web:
    image: nginx:latest
    networks:
      - frontend
    # 指定IP地址
    networks:
      frontend:
        ipv4_address: 172.20.0.100

networks:
  frontend:
    ipam:
      config:
        - subnet: 172.20.0.0/16

网络配置:

networks:
  # 默认网络
  frontend:
  
  # 自定义网络
  backend:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16
          gateway: 172.20.0.1
  
  # 使用已存在的网络
  external:
    external: true
    name: my-existing-network

2.2.4 数据卷配置

数据卷挂载:

services:
  web:
    image: nginx:latest
    volumes:
      # 命名卷
      - web_data:/usr/share/nginx/html
      # 绑定挂载
      - ./html:/usr/share/nginx/html
      # 匿名卷
      - /usr/share/nginx/html
      # 只读挂载
      - ./config:/etc/nginx/conf.d:ro

volumes:
  web_data:
    driver: local

数据卷配置:

volumes:
  # 命名卷
  web_data:
  
  # 指定驱动
  db_data:
    driver: local
    driver_opts:
      type: none
      device: /data/db
      o: bind
  
  # 使用已存在的卷
  existing_data:
    external: true
    name: my-existing-volume

2.2.5 依赖配置

服务依赖:

services:
  web:
    image: nginx:latest
    depends_on:
      - api
      - db
  
  api:
    image: myapi:latest
    depends_on:
      - db
  
  db:
    image: mysql:5.7

依赖条件:

services:
  api:
    image: myapi:latest
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
  
  db:
    image: mysql:5.7
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

三、Compose命令详解

3.1 基本命令

3.1.1 启动服务

docker compose up:

# 前台启动
docker compose up

# 后台启动
docker compose up -d

# 构建后启动
docker compose up --build

# 强制重新创建容器
docker compose up --force-recreate

# 不启动依赖服务
docker compose up --no-deps web

# 指定项目名称
docker compose -p myproject up -d

# 指定配置文件
docker compose -f docker-compose.prod.yml up -d

启动流程:

docker compose up执行流程:
├─ 读取docker-compose.yml文件
├─ 创建网络和数据卷
├─ 拉取或构建镜像
├─ 创建容器
├─ 启动容器
└─ 显示日志(前台模式)

3.1.2 停止服务

docker compose down:

# 停止并删除容器
docker compose down

# 同时删除数据卷
docker compose down -v

# 同时删除镜像
docker compose down --rmi all

# 同时删除网络
docker compose down --remove-orphans

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

# 启动已停止的服务
docker compose start

# 重启服务
docker compose restart

3.2 管理命令

3.2.1 查看状态

docker compose ps:

# 查看服务状态
docker compose ps

# 输出
NAME                COMMAND                  SERVICE             STATUS              PORTS
myproject-web-1     "/docker-entrypoint.…"   web                 running             0.0.0.0:8080->80/tcp
myproject-api-1     "node app.js"            api                 running             0.0.0.0:3000->3000/tcp
myproject-db-1      "docker-entrypoint.s…"   db                  running             3306/tcp

# 查看所有容器(包括停止的)
docker compose ps -a

docker compose logs:

# 查看所有服务日志
docker compose logs

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

# 实时查看日志
docker compose logs -f

# 查看最后100行日志
docker compose logs --tail=100

# 查看带时间戳的日志
docker compose logs -t

3.2.2 执行命令

docker compose exec:

# 进入容器
docker compose exec web bash

# 以root用户进入
docker compose exec -u root web bash

# 执行单个命令
docker compose exec web ls /app

# 指定工作目录
docker compose exec -w /app web ls

docker compose run:

# 运行一次性命令
docker compose run web ping google.com

# 运行交互式命令
docker compose run web bash

# 不启动依赖服务
docker compose run --no-deps web bash

# 删除运行后的容器
docker compose run --rm web ls

3.2.3 其他命令

docker compose config:

# 验证配置文件
docker compose config

# 查看完整配置
docker compose config

# 查看服务名称
docker compose config --services

# 查看数据卷名称
docker compose config --volumes

docker compose images:

# 查看服务使用的镜像
docker compose images

# 输出
Container           Repository          Tag                 Image Id            Size
myproject-web-1     nginx               latest              a1b2c3d4e5f6        142MB
myproject-api-1     myapi               latest              b2c3d4e5f6a7        120MB
myproject-db-1      mysql               5.7                 c3d4e5f6a7b8        448MB

docker compose top:

# 查看容器进程
docker compose top

# 输出
myproject-web-1
UID    PID     PPID    C    STIME   TTY   TIME       CMD
root   12345   12340   0    10:00   ?     00:00:00   nginx: master process nginx-
101    12346   12345   0    10:00   ?     00:00:00   nginx: worker process

四、环境变量

4.1 环境变量配置

4.1.1 环境变量文件

.env文件:

# .env文件
# 数据库配置
MYSQL_ROOT_PASSWORD=root123
MYSQL_DATABASE=mydb
MYSQL_USER=myuser
MYSQL_PASSWORD=mypassword

# 应用配置
APP_ENV=production
APP_DEBUG=false
APP_PORT=3000

# 端口配置
WEB_PORT=8080
API_PORT=3000
DB_PORT=3306

使用环境变量:

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "${WEB_PORT}:80"
  
  api:
    image: myapi:latest
    environment:
      - APP_ENV=${APP_ENV}
      - APP_DEBUG=${APP_DEBUG}
    ports:
      - "${API_PORT}:3000"
  
  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    ports:
      - "${DB_PORT}:3306"

4.1.2 环境变量优先级

优先级顺序:

环境变量优先级(从高到低):
1. Shell环境变量
2. docker compose命令行参数
3. .env文件
4. docker-compose.yml中的默认值

示例:
# Shell环境变量
export MYSQL_ROOT_PASSWORD=newpassword
docker compose up -d
# 使用newpassword

# 命令行参数
MYSQL_ROOT_PASSWORD=cmdpassword docker compose up -d
# 使用cmdpassword

# .env文件
MYSQL_ROOT_PASSWORD=envpassword
docker compose up -d
# 使用envpassword

4.2 多环境配置

4.2.1 多配置文件

开发环境:

# docker-compose.yml
version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
  
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    volumes:
      - .:/app

生产环境:

# docker-compose.prod.yml
version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    restart: always
  
  api:
    image: myregistry.com/myapi:latest
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    restart: always

使用方法:

# 开发环境
docker compose up -d

# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 或使用环境变量
export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
docker compose up -d

4.2.2 环境变量文件分离

多个环境变量文件:

# .env.development
APP_ENV=development
DEBUG=true

# .env.production
APP_ENV=production
DEBUG=false

# .env.test
APP_ENV=test
DEBUG=true

使用方法:

# 开发环境
docker compose --env-file .env.development up -d

# 生产环境
docker compose --env-file .env.production up -d

# 测试环境
docker compose --env-file .env.test up -d

五、实战案例

5.1 WordPress博客系统

5.1.1 完整配置

docker-compose.yml:

version: '3.8'

services:
  # WordPress服务
  wordpress:
    image: wordpress:latest
    container_name: wordpress
    restart: always
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    networks:
      - wordpress-net
    depends_on:
      - db

  # MySQL数据库
  db:
    image: mysql:5.7
    container_name: wordpress-db
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - wordpress-net

# 数据卷
volumes:
  wordpress_data:
  db_data:

# 网络
networks:
  wordpress-net:

启动服务:

# 启动WordPress
docker compose up -d

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f

# 访问WordPress
# http://localhost:8080

5.2 微服务应用

5.2.1 完整配置

docker-compose.yml:

version: '3.8'

services:
  # 前端服务
  frontend:
    build: ./frontend
    container_name: frontend
    restart: always
    ports:
      - "80:80"
    networks:
      - frontend-net
    depends_on:
      - backend

  # 后端服务
  backend:
    build: ./backend
    container_name: backend
    restart: always
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - DB_PORT=3306
      - DB_NAME=myapp
      - DB_USER=root
      - DB_PASSWORD=root123
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    networks:
      - frontend-net
      - backend-net
    depends_on:
      - db
      - redis

  # 数据库服务
  db:
    image: mysql:5.7
    container_name: mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=root123
      - MYSQL_DATABASE=myapp
    volumes:
      - db_data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - backend-net

  # 缓存服务
  redis:
    image: redis:alpine
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    networks:
      - backend-net

# 数据卷
volumes:
  db_data:
  redis_data:

# 网络
networks:
  frontend-net:
  backend-net:

项目结构:

myapp/
├── docker-compose.yml
├── frontend/
│   ├── Dockerfile
│   └── src/
├── backend/
│   ├── Dockerfile
│   └── src/
└── init.sql

启动服务:

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

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs -f backend

# 扩展后端服务
docker compose up -d --scale backend=3

六、本章小结

6.1 Compose核心概念

6.1.1 核心概念总结

Compose核心概念:
├─ 项目(Project): 一组关联的服务
├─ 服务(Service): 应用的容器
├─ 网络(Network): 服务间通信
├─ 数据卷(Volume): 数据持久化
└─ 配置(Config): 应用配置

Compose文件结构:
├─ version: 文件版本
├─ services: 服务定义
├─ networks: 网络定义
├─ volumes: 数据卷定义
├─ configs: 配置定义
└─ secrets: 密钥定义

6.1.2 命令总结

服务管理:
├─ docker compose up: 启动服务
├─ docker compose down: 停止并删除服务
├─ docker compose start: 启动服务
├─ docker compose stop: 停止服务
├─ docker compose restart: 重启服务
└─ docker compose pause/unpause: 暂停/恢复服务

服务查看:
├─ docker compose ps: 查看服务状态
├─ docker compose logs: 查看日志
├─ docker compose top: 查看进程
├─ docker compose images: 查看镜像
└─ docker compose config: 验证配置

服务操作:
├─ docker compose exec: 在容器中执行命令
├─ docker compose run: 运行一次性命令
├─ docker compose build: 构建镜像
└─ docker compose pull: 拉取镜像

6.2 最佳实践

6.2.1 配置建议

文件组织:
✅ 使用版本控制管理配置文件
✅ 使用环境变量管理敏感信息
✅ 使用多配置文件管理多环境
✅ 合理命名服务和数据卷

服务配置:
✅ 设置合理的重启策略
✅ 配置健康检查
✅ 设置资源限制
✅ 使用依赖管理

网络和存储:
✅ 使用自定义网络
✅ 使用命名卷持久化数据
✅ 合理配置网络隔离
✅ 定期备份数据

6.2.2 性能优化

构建优化:
✅ 使用多阶段构建
✅ 优化构建缓存
✅ 减小镜像大小
✅ 使用.dockerignore

运行优化:
✅ 设置资源限制
✅ 使用健康检查
✅ 优化日志配置
✅ 监控服务状态

6.3 下一章预告

下一章: Docker Compose进阶

将学习:

  • 🎼 高级配置技巧
  • 🚀 服务扩展与负载均衡
  • 📦 配置管理
  • 🔧 密钥管理

📝 练习题

基础题

  1. 基本使用: 创建一个docker-compose.yml文件,启动一个nginx服务,映射端口8080:80,并验证访问。

  2. 多服务编排: 创建一个包含nginx和redis两个服务的docker-compose.yml文件,nginx使用自定义配置,redis设置密码。

  3. 数据持久化: 创建一个MySQL服务的docker-compose.yml文件,使用数据卷持久化数据,插入测试数据后删除容器,重新创建验证数据是否保留。

进阶题

  1. 环境变量: 创建一个使用环境变量的docker-compose.yml文件,包含多个服务,使用.env文件管理配置,并支持多环境部署。

  2. 服务依赖: 创建一个三层架构应用的docker-compose.yml文件,包含前端、后端、数据库,配置服务依赖和健康检查。

  3. 网络隔离: 创建一个包含多个网络的docker-compose.yml文件,实现前端、后端、数据库的网络隔离。

实践题

  1. 完整应用: 为一个博客系统设计docker-compose.yml文件,要求:

    • WordPress前端
    • MySQL数据库
    • Redis缓存
    • Nginx反向代理
    • 数据持久化
    • 网络隔离
  2. 多环境部署: 为一个微服务应用设计多环境部署方案,要求:

    • 开发环境配置
    • 测试环境配置
    • 生产环境配置
    • 环境变量管理
    • 一键切换环境