Docker学习路径——10、Docker Compose 一站式编排:从入门到生产级部署

Docker Compose 一站式编排:从入门到生产级部署

在微服务架构中,单个应用往往由多个相互依赖的容器 组成(如 Web 服务器 + 数据库 + 缓存)。手动管理这些容器(docker run 启动、依赖顺序、网络配置)既繁琐又易错。Docker Compose 应运而生------它用声明式 YAML 文件 定义整个应用栈,实现 "一键部署、一键销毁"

为什么必须用 Compose

  • 简化复杂度 :10 行 YAML 替代 10 条 docker run 命令
  • 依赖管理:自动处理启动顺序(如 DB 先于 Web 启动)
  • 环境一致性:开发、测试、生产环境配置统一
  • 资源隔离:每个项目独立网络/卷,避免冲突

一、核心概念解析

1. 三大核心要素

要素 说明 示例
Project(项目) 一组关联服务的集合 my-web-app
Service(服务) 单个容器实例的配置模板 web, db, redis
Compose File 定义项目的 YAML 文件 docker-compose.yml

2. 工作流程

docker-compose.yml
Docker Compose
解析配置
创建网络
拉取镜像
启动容器
按依赖顺序启动


二、安装与验证

安装步骤(Linux)

bash 复制代码
# 下载二进制文件
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

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

# 创建软链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 验证安装
docker-compose --version
# 输出:Docker Compose version v2.24.5

💡 替代方案

若 GitHub 下载慢,可从 DaoCloud 镜像 获取


三、Compose 文件深度解析

基础结构(v3.8 规范)

yaml 复制代码
version: "3.8"  # 指定 Compose 文件版本

services:
  web:          # 服务名(自定义)
    image: nginx:alpine
    ports:
      - "80:80"
    networks:
      - app-net

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - db-data:/var/lib/mysql

# 定义命名卷
volumes:
  db-data:

# 定义自定义网络
networks:
  app-net:
    driver: bridge

关键字段详解

字段 作用 最佳实践
image 指定镜像 优先使用带 tag 的镜像(如 redis:7.0
build 从 Dockerfile 构建 image 二选一
ports 端口映射 生产环境慎用(建议仅暴露必要端口)
volumes 数据卷挂载 用命名卷替代绑定挂载(更便携)
environment 环境变量 敏感信息用 env_file 或 secrets
depends_on 启动依赖 注意:仅控制启动顺序,不等待服务就绪
networks 网络连接 必须先定义网络

⚠️ depends_on 陷阱

它只保证容器启动顺序,不等待服务真正可用

解决方案:在应用代码中添加重试逻辑,或使用 healthcheck


四、实战案例:修复你的 Compose 文件

你提供的配置存在几个关键问题,以下是修正版:

修正后的 docker-compose.yml

yaml 复制代码
version: "3.8"

services:
  # Tomcat 服务(原 cenos 名称有误)
  tomcat:
    image: billygoo/tomcat8-jdk8
    container_name: test01
    ports:
      - "8080:8080"  # 添加端口映射(否则无法外部访问)
    networks:
      - xn_network
    depends_on:
      - redis
      - mysql
    # 添加健康检查(确保 Tomcat 就绪)
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080"]
      interval: 30s
      timeout: 10s
      retries: 3

  redis:
    image: redis  # 修正拼写(原 images → image)
    ports:
      - "6379:6379"
    volumes:
      - /opt/redis/redis.conf:/etc/redis/redis.conf:ro  # 只读挂载配置
      - redis-data:/data  # 使用命名卷(更安全)
    networks:
      - xn_network
    command: redis-server /etc/redis/redis.conf
    # Redis 健康检查
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

  mysql:
    image: mysql:5.7  # 修正拼写
    environment:
      MYSQL_ROOT_PASSWORD: "123456"
      MYSQL_DATABASE: "db2021"
      MYSQL_USER: "xn"
      MYSQL_PASSWORD: "123456"
    volumes:
      - mysql-data:/var/lib/mysql  # 命名卷
      - /opt/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro  # 配置文件路径修正
    networks:
      - xn_network
    # MySQL 健康检查
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 3

# 定义命名卷(避免直接挂载宿主机路径)
volumes:
  redis-data:
  mysql-data:

# 定义网络
networks:
  xn_network:
    driver: bridge

关键修正点:

  1. 拼写错误imagesimage
  2. 端口映射 :为 Tomcat 添加 8080:8080
  3. 数据卷优化
    • 使用命名卷(redis-data, mysql-data)替代直接挂载
    • 配置文件挂载为只读(:ro
  4. 健康检查:确保服务真正就绪后再启动依赖服务
  5. 配置路径 :MySQL 配置应放在 /etc/mysql/conf.d/

五、常用命令速查

命令 作用 场景
docker-compose up -d 后台启动所有服务 部署应用
docker-compose down 停止并删除容器/网络 清理环境
docker-compose logs -f web 实时查看日志 调试
docker-compose exec db mysql -u root -p 进入容器执行命令 数据库操作
docker-compose config 验证 YAML 语法 部署前检查
docker-compose ps 查看服务状态 监控

💡 项目命名

默认以目录名为项目名,可通过 -p 指定:

bash 复制代码
docker-compose -p myapp up -d

六、高级技巧

1. 环境变量分离

创建 .env 文件:

env 复制代码
DB_PASSWORD=supersecret
REDIS_HOST=redis

在 compose 文件中引用:

yaml 复制代码
environment:
  MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}

2. 多环境配置

  • docker-compose.yml:基础配置
  • docker-compose.override.yml:开发环境覆盖(自动加载)
  • docker-compose.prod.yml:生产环境配置
bash 复制代码
# 生产环境启动
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

3. 扩展服务(Scale)

bash 复制代码
# 启动 3 个 Redis 实例(需无状态服务)
docker-compose up --scale redis=3 -d

七、生产环境最佳实践

1. 安全加固

  • 敏感信息:使用 Docker secrets(Swarm 模式)或 HashiCorp Vault
  • 最小权限:容器以非 root 用户运行
  • 网络隔离:前端/后端服务分属不同网络

2. 资源限制

yaml 复制代码
services:
  web:
    deploy:  # 仅 Swarm 模式有效
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    # Compose 模式用以下方式
    mem_limit: 512m
    cpus: 0.5

3. 监控集成

  • 挂载 /var/run/docker.sock 给监控容器
  • 使用 Prometheus + cAdvisor 收集指标

八、常见问题排查

Q1:服务启动顺序问题

  • 现象:Web 服务因 DB 未就绪而崩溃
  • 解决方案
    1. 添加 healthcheck
    2. 在应用代码中实现连接重试
    3. 使用 wait-for-it.sh 脚本(GitHub 链接

Q2:卷权限错误

  • 现象:MySQL 容器因权限拒绝启动

  • 解决方案

    bash 复制代码
    # 初始化卷权限
    docker run --rm -v mysql-data:/var/lib/mysql alpine chown -R 999:999 /var/lib/mysql

Q3:网络 DNS 解析失败

  • 现象:容器内无法通过服务名访问其他服务

  • 检查点

    bash 复制代码
    # 进入容器检查 DNS
    docker-compose exec web cat /etc/resolv.conf
    # 应包含 nameserver 127.0.0.11(Docker 内置 DNS)

九、总结:Compose 黄金法则

  1. 明确依赖 :用 depends_on + healthcheck 双保险
  2. 持久化数据:数据库必须用命名卷
  3. 配置分离:敏感信息绝不硬编码
  4. 资源限制:防止单个服务耗尽资源
  5. 版本锁定 :Compose 文件指定 version

🚀 行动清单

  • 将现有 docker run 命令迁移至 Compose
  • 为团队制定 Compose 文件规范
  • 在 CI/CD 中集成 docker-compose config 验证

掌握 Docker Compose,你就拥有了高效管理多容器应用 的核心能力。下一步,我们将探索如何用 Docker SwarmKubernetes 实现集群化部署!

相关推荐
zhangrelay2 小时前
三分钟云课实践速通--概率统计--python版
linux·开发语言·笔记·python·学习·ubuntu
小菜同学爱学习2 小时前
兜底保障!MySQL运维实战与常见问题排查全解析
运维·mysql·adb
雅斯驰2 小时前
工业自动化、物联网传感器、车身控制:PIC18F26K20-I/ML的典型应用场景
运维·物联网·自动化
云栖梦泽2 小时前
Linux内核与驱动:GPIO设备树与SPI设备树的区别
linux·运维·c++·嵌入式硬件
smallcelebration2 小时前
132 docker入门学习
学习·docker·容器
A-刘晨阳2 小时前
K8s 之 Ingress 及 Ingress Controller
云原生·容器·kubernetes·负载均衡·ingress
HalvmånEver2 小时前
MySQL表的查询(二)
linux·数据库·学习·mysql
断问天2 小时前
Faq:Fedora44 Kernel升级后WIFI和声卡都不能使用了
linux·运维·服务器
zjeweler2 小时前
云服务器部署 Claude Code 实战指南
运维·服务器·claude code