Docker Compose 概述
什么是 Docker Compose?
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件,我们可以配置应用程序的服务、网络、卷等,然后使用单个命令来创建和启动所有服务。
Docker Compose 的优势
- 简化配置:使用 YAML 文件统一配置所有服务
- 一键部署:通过单个命令启动整个应用栈
- 环境一致性:确保开发、测试和生产环境的一致性
- 服务依赖管理:自动处理服务间的依赖关系
- 扩展性:方便地扩展或缩服务实例
Docker Compose 安装
在 Linux 系统上安装
# 下载最新版本的 Docker Compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
在 Windows 和 macOS 上安装
Docker Desktop for Windows 和 macOS 已经内置了 Docker Compose,安装 Docker Desktop 即可使用。
Docker Compose 核心概念
docker-compose.yml 文件结构
version: '3.8'
services:
service1:
# 服务配置
service2:
# 服务配置
networks:
# 网络配置
volumes:
# 卷配置
主要配置选项
- image:指定服务使用的镜像
- build:指定构建镜像的 Dockerfile 路径
- ports:端口映射
- volumes:数据卷挂载
- environment:环境变量
- depends_on:服务依赖关系
- networks:网络配置
- restart:重启策略
- command:覆盖容器的默认命令
基础实战:部署 WordPress 应用
步骤 1:创建 docker-compose.yml 文件
version: '3.8'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data:
wordpress_data:
步骤 2:启动服务
# 启动服务(后台运行)
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs
# 查看特定服务的日志
docker-compose logs wordpress
步骤 3:访问应用
在浏览器中访问 http://localhost:8000,即可看到 WordPress 安装页面。
步骤 4:停止和清理
# 停止服务
docker-compose stop
# 启动服务
docker-compose start
# 重启服务
docker-compose restart
# 停止并删除容器、网络和卷
docker-compose down -v
进阶实战:部署完整的微服务架构
示例:电商系统微服务架构
version: '3.8'
services:
# 前端服务
frontend:
build: ./frontend
ports:
- "3000:3000"
depends_on:
- api
environment:
- API_URL=http://api:8000
# API 网关
api:
build: ./api
ports:
- "8000:8000"
depends_on:
- product-service
- order-service
- user-service
environment:
- PRODUCT_SERVICE_URL=http://product-service:8001
- ORDER_SERVICE_URL=http://order-service:8002
- USER_SERVICE_URL=http://user-service:8003
# 产品服务
product-service:
build: ./product-service
depends_on:
- product-db
environment:
- DB_HOST=product-db
- DB_PORT=5432
- DB_NAME=product
- DB_USER=postgres
- DB_PASSWORD=secret
# 订单服务
order-service:
build: ./order-service
depends_on:
- order-db
environment:
- DB_HOST=order-db
- DB_PORT=5432
- DB_NAME=order
- DB_USER=postgres
- DB_PASSWORD=secret
# 用户服务
user-service:
build: ./user-service
depends_on:
- user-db
environment:
- DB_HOST=user-db
- DB_PORT=5432
- DB_NAME=user
- DB_USER=postgres
- DB_PASSWORD=secret
# 数据库服务
product-db:
image: postgres:13
volumes:
- product-db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=product
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
order-db:
image: postgres:13
volumes:
- order-db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=order
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
user-db:
image: postgres:13
volumes:
- user-db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=user
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
# 消息队列
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"
volumes:
- rabbitmq-data:/var/lib/rabbitmq
# 缓存
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- redis-data:/data
# 网络配置
networks:
default:
name: ecommerce-network
# 卷配置
volumes:
product-db-data:
order-db-data:
user-db-data:
rabbitmq-data:
redis-data:
部署和管理
# 构建并启动所有服务
docker-compose up -d --build
# 查看服务状态
docker-compose ps
# 扩展服务实例(例如,将产品服务扩展到 3 个实例)
docker-compose up -d --scale product-service=3
# 查看服务日志(跟踪模式)
docker-compose logs -f
# 进入特定服务容器
docker-compose exec api bash
# 执行服务健康检查
docker-compose exec product-service curl -s http://localhost:8001/health
高级配置技巧
1. 使用环境变量文件
创建 .env 文件:
# 数据库配置
DB_HOST=db
DB_PORT=5432
DB_NAME=app
DB_USER=postgres
DB_PASSWORD=secret
# 应用配置
APP_ENV=production
APP_DEBUG=false
在 docker-compose.yml 中使用:
services:
app:
image: my-app
environment:
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- APP_ENV=${APP_ENV}
- APP_DEBUG=${APP_DEBUG}
2. 使用 extends 指令复用配置
创建 common.yml 文件:
services:
base-service:
image: node:14-alpine
restart: always
environment:
- NODE_ENV=production
volumes:
- .:/app
working_dir: /app
在 docker-compose.yml 中使用:
extends:
file: common.yml
service: base-service
services:
api:
extends:
file: common.yml
service: base-service
ports:
- "8000:8000"
command: npm run start:api
worker:
extends:
file: common.yml
service: base-service
command: npm run start:worker
3. 多环境配置
创建 docker-compose.override.yml 文件,用于开发环境覆盖默认配置:
services:
app:
environment:
- APP_ENV=development
- APP_DEBUG=true
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
command: npm run dev
Docker Compose 会自动加载 docker-compose.override.yml 文件,覆盖默认配置。
4. 健康检查配置
services:
app:
image: my-app
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: postgres:13
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
监控与日志管理
1. 集中式日志管理
services:
# 应用服务
app:
image: my-app
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: app.{{.Name}}
# Fluentd 服务
fluentd:
image: fluent/fluentd:v1.14-debian
volumes:
- ./fluentd/conf:/fluentd/etc
- fluentd-data:/fluentd/log
ports:
- "24224:24224"
# Elasticsearch 服务
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
environment:
- discovery.type=single-node
volumes:
- es-data:/usr/share/elasticsearch/data
# Kibana 服务
kibana:
image: docker.elastic.co/kibana/kibana:7.14.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
volumes:
fluentd-data:
es-data:
2. 服务监控
services:
# 应用服务
app:
image: my-app
ports:
- "3000:3000"
# Prometheus 服务
prometheus:
image: prom/prometheus:v2.28.0
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
# Grafana 服务
grafana:
image: grafana/grafana:8.1.0
volumes:
- grafana-data:/var/lib/grafana
ports:
- "3001:3000"
depends_on:
- prometheus
volumes:
grafana-data:
常见问题与解决方案
1. 服务启动顺序问题
问题:依赖服务尚未就绪,导致服务启动失败。
解决方案:
- 使用
depends_on定义服务依赖关系 - 实现服务启动重试机制
- 使用健康检查确保依赖服务就绪
2. 资源限制问题
问题:服务使用过多资源,导致系统性能下降。
解决方案:
- 为服务设置资源限制:
services:
app:
image: my-app
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
3. 网络连接问题
问题:服务间网络连接不稳定。
解决方案:
- 为服务指定固定的网络别名
- 实现网络连接重试机制
- 使用 Docker 网络的内置 DNS 服务
4. 数据持久化问题
问题:容器重启后数据丢失。
解决方案:
- 使用命名卷进行数据持久化
- 配置适当的卷备份策略
- 考虑使用外部存储服务
最佳实践
1. 配置管理
- 使用环境变量文件管理配置:
.env文件 - 为不同环境创建不同的配置文件:
docker-compose.prod.yml、docker-compose.dev.yml - 避免在配置文件中硬编码敏感信息,使用 Docker secrets 或环境变量
2. 镜像管理
- 使用多阶段构建减少镜像大小
- 为镜像添加合理的标签,避免使用 latest 标签
- 定期清理未使用的镜像和容器
3. 服务设计
- 每个服务只负责一个功能,遵循单一职责原则
- 服务间通过网络协议通信,避免共享文件系统
- 为服务实现健康检查和优雅启动/关闭机制
4. 部署策略
- 使用 CI/CD 管道自动化部署流程
- 实现蓝绿部署或滚动更新,减少服务 downtime
- 定期备份关键数据和配置
5. 监控与维护
- 实现集中式日志管理,便于问题排查
- 配置服务监控,及时发现性能瓶颈和故障
- 建立完善的告警机制,确保服务可靠性
总结
Docker Compose 是一个强大的工具,它简化了多容器应用的管理和部署。通过本文的学习,你应该已经掌握了 Docker Compose 的基础用法、进阶技巧和最佳实践,能够使用它来部署从简单应用到复杂微服务架构的各种场景。
作为一名运维工程师,掌握 Docker Compose 技术可以大大提高工作效率,实现应用的快速部署和管理。在实际工作中,我们需要根据具体的应用场景和需求,灵活运用 Docker Compose 的各种功能,不断优化配置,才能真正发挥其最大价值。