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
关键修正点:
- 拼写错误 :
images→image - 端口映射 :为 Tomcat 添加
8080:8080 - 数据卷优化 :
- 使用命名卷(
redis-data,mysql-data)替代直接挂载 - 配置文件挂载为只读(
:ro)
- 使用命名卷(
- 健康检查:确保服务真正就绪后再启动依赖服务
- 配置路径 :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指定:
bashdocker-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 未就绪而崩溃
- 解决方案 :
- 添加
healthcheck - 在应用代码中实现连接重试
- 使用
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 黄金法则
- 明确依赖 :用
depends_on+healthcheck双保险 - 持久化数据:数据库必须用命名卷
- 配置分离:敏感信息绝不硬编码
- 资源限制:防止单个服务耗尽资源
- 版本锁定 :Compose 文件指定
version
🚀 行动清单:
- 将现有
docker run命令迁移至 Compose- 为团队制定 Compose 文件规范
- 在 CI/CD 中集成
docker-compose config验证
掌握 Docker Compose,你就拥有了高效管理多容器应用 的核心能力。下一步,我们将探索如何用 Docker Swarm 或 Kubernetes 实现集群化部署!