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 实现集群化部署!

相关推荐
一叶龙洲5 小时前
wslg打开Ubuntu24.04默认打开图形界面
linux·服务器·数据库·ubuntu
敖行客 Allthinker7 小时前
Parallels Ubuntu虚拟机项目如何让手机访问?完整解决方案
linux·运维·ubuntu
BullSmall8 小时前
Anolis OS 8.10 完整安装 Docker CE(生产可用,解决 podman 冲突)
docker·容器·podman
keyipatience8 小时前
线程栈与TLS和线程互斥
java·linux·服务器·开发语言·ubuntu
元Y亨H8 小时前
生产环境监控与故障应急处理(5-5-5 标准)指南
运维
j7~8 小时前
【Linux】二十二.《Linux 信号机制完全指南:表示、捕捉与处理》
linux·信号处理·volatile·可入重函数·保存信号
踏月的造梦星球8 小时前
达梦数据库执行计划与性能分析入门:EXPLAIN、AUTOTRACE 与 ET
服务器·数据库·oracle
观山岳五楼9 小时前
Ubuntu 24 怎么使用Ubuntu 20 的镜像源
linux·运维·ubuntu
星夜夏空999 小时前
网络编程(1)
服务器·网络
川石课堂软件测试9 小时前
安全测试|常见SQL注入攻击方式、实例及预防
服务器·数据库·sql·功能测试·测试工具·安全·单元测试