Docker Compose 使用完全指南
1. 什么是Docker Compose?
Docker Compose是Docker官方提供的用于定义和运行多容器Docker应用程序的工具。通过一个简单的YAML文件配置应用程序的所有服务,然后使用单个命令创建并启动所有服务。Docker Compose特别适合开发、测试和CI/CD环境,能够显著简化多容器应用的部署流程。
与Docker CLI相比,Docker Compose的主要优势在于:
集中管理多个容器
一键启动/停止整个应用栈
自动化容器间网络配置
轻松实现服务扩展和负载均衡
完整的开发工作流支持
2. 安装Docker Compose
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
# 创建软链接(可选)
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 验证安装
docker-compose version
2.2. macOS系统安装
# 使用Homebrew安装
brew install docker-compose
# 验证安装
docker-compose --version
2.3. Windows系统安装
下载Docker Desktop for Windows:https://www.docker.com/products/docker-desktop
安装时确保启用"Include Docker Compose"选项
安装完成后在PowerShell中验证:
docker-compose version
3. Docker Compose核心概念
3.1. 服务(Services)
服务代表应用中的一个组件,例如Web服务器、数据库、缓存等。在docker-compose.yml文件中定义服务的配置。
3.2. 容器(Containers)
基于服务配置创建的运行实例。每个服务可以包含一个或多个容器实例。
3.3. 网络(Networks)
提供容器间的通信通道。Docker Compose会自动创建默认网络,也可以自定义网络配置。
3.4. 卷(Volumes)
用于持久化数据和容器间共享数据。可以挂载主机目录或使用Docker管理的卷。
3.5. 项目(Projects)
由docker-compose.yml文件定义的一组关联服务。项目名称默认为目录名,也可通过-p参数指定。
4. 编写docker-compose.yml文件
docker-compose.yml是Docker Compose的核心配置文件,使用YAML格式定义服务、网络和卷。
4.1. 文件结构示例
version: '3.8' # Docker Compose文件格式版本
services: # 服务定义部分
webapp: # 服务名称
image: nginx:alpine # 使用的基础镜像
ports: # 端口映射
- "8080:80"
volumes: # 数据卷挂载
- ./html:/usr/share/nginx/html
networks: # 使用的网络
- webnet
depends_on: # 依赖关系
- database
database:
image: mysql:5.7
environment: # 环境变量
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- dbdata:/var/lib/mysql
networks:
- webnet
volumes: # 顶级卷定义
dbdata: # 命名卷
networks: # 顶级网络定义
webnet: # 自定义网络
driver: bridge
4.2. 指令详解
version:指定Docker Compose文件格式版本
services:定义所有服务
image:指定镜像(优先使用本地镜像,不存在则拉取)
build:从Dockerfile构建镜像
build:
context: ./dir # 构建上下文路径
dockerfile: Dockerfile-dev # 自定义Dockerfile名称
args: # 构建参数
BUILD_VERSION: 1.0
ports:端口映射(主机:容器)
ports:
- "8080:80" # 主机8080端口映射到容器80端口
- "9000-9010:9000" # 主机端口范围映射
volumes:数据卷挂载
volumes:
- ./html:/usr/share/nginx/html # 绑定挂载(主机目录:容器目录)
- dbdata:/var/lib/mysql # 命名卷(卷名:容器路径)
- /data:/data:ro # 只读挂载
environment:环境变量
environment:
- DEBUG=true
- DB_HOST=database
- PASSWORD=secret # 敏感信息建议使用环境文件
env_file:从文件加载环境变量
env_file:
- ./common.env
- ./apps/web.env
depends_on:服务依赖顺序
depends_on:
- database
- redis
networks:网络配置
networks:
- frontnet
- backnet
command:覆盖容器默认命令
command: python manage.py runserver 0.0.0.0:8000
restart:重启策略
restart: unless-stopped # 选项:no, always, on-failure, unless-stopped
healthcheck:健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
secrets:敏感数据管理(需Swarm模式)
secrets:
- db_password
secrets:
db_password:
file: ./db_password.txt
volumes:顶级卷定义(可选)
networks:顶级网络定义(可选)
4.3. 完整示例:WordPress应用
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
networks:
- wpnet
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 20s
timeout: 10s
retries: 5
wordpress:
depends_on:
db:
condition: service_healthy
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp-content:/var/www/html/wp-content
networks:
- wpnet
volumes:
db_data:
networks:
wpnet:
driver: bridge
5. Docker Compose命令详解
5.1. 基本命令格式
docker-compose [选项] [命令] [服务]
5.2. 常用命令
构建和启动
# 后台启动所有服务
docker-compose up -d
# 构建镜像后启动(适用于使用build指令的服务)
docker-compose up --build
# 启动特定服务
docker-compose up -d webapp
停止和删除
# 停止所有服务
docker-compose stop
# 停止并删除容器、网络、卷(保留命名卷)
docker-compose down
# 停止并删除所有资源(包括命名卷)
docker-compose down -v
# 删除停止的服务容器
docker-compose rm -f
查看状态
# 列出所有容器
docker-compose ps
# 查看服务日志(实时跟踪)
docker-compose logs -f webapp
# 查看最后20条日志
docker-compose logs --tail=20
服务操作
# 启动已停止的服务
docker-compose start db
# 停止运行中的服务
docker-compose stop webapp
# 重启服务
docker-compose restart webapp
# 构建或重新构建服务
docker-compose build webapp
# 强制重新构建(不使用缓存)
docker-compose build --no-cache
容器内操作
# 在容器内执行命令(交互式)
docker-compose exec webapp bash
# 在容器内执行单个命令
docker-compose exec db mysql -u root -p
扩展服务
# 启动3个web实例
docker-compose up -d --scale webapp=3
# 查看扩展结果
docker-compose ps
5.3. 高级选项
指定项目名称
docker-compose -p myproject up -d
使用自定义配置文件
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
强制重新创建容器
docker-compose up -d --force-recreate
不使用缓存启动
docker-compose up -d --force-recreate --build --no-deps
6. 网络配置详解
6.1. 默认网络行为
Docker Compose自动创建名为<项目名>_default的网络
所有服务加入该默认网络
服务名可作为主机名在容器间访问
6.2. 自定义网络
version: '3.8'
services:
frontend:
image: nginx
networks:
- frontend
- backend
backend:
image: myapp
networks:
- backend
- database
database:
image: mysql
networks:
- database
networks:
frontend:
driver: bridge
backend:
driver: bridge
database:
driver: bridge
internal: true # 禁止外部访问
6.3. 网络高级配置
networks:
mynet:
driver: overlay # 用于Swarm集群
driver_opts:
com.docker.network.enable_ipv6: "true"
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
7. 数据卷管理
7.1. 卷类型对比
| 类型 | 特点 | 适用场景 |
|------|------|----------|
| 绑定挂载 | 直接映射主机目录 | 开发时实时同步 |
| 命名卷 | Docker管理 | 生产环境持久化 |
| 临时卷 | 容器内目录 | 临时数据处理 |
7.2. 卷配置示例
version: '3.8'
services:
app:
image: myapp
volumes:
# 绑定挂载(开发时使用)
- ./src:/app/src
# 命名卷(生产环境)
- app_data:/app/data
# 只读挂载
- ./config:/app/config:ro
# 临时卷
- temp_data:/tmp
volumes:
app_data: # 命名卷
temp_data: # 临时卷
7.3. 卷高级选项
volumes:
data:
driver: local
driver_opts:
type: none # 使用NFS
o: bind
device: /nfs/data # NFS路径
8. 环境变量管理
8.1. 环境变量优先级
docker-compose.yml中定义的environment
env_file中定义的变量
主机环境变量(通过--env-file指定)
8.2. 环境变量使用技巧
在docker-compose.yml中引用变量
web:
image: "${WEB_IMAGE_TAG:-latest}"
environment:
- API_KEY=${API_KEY}
command: ["${START_CMD}", "run"]
使用.env文件
# .env文件内容
DB_HOST=db
DB_PORT=3306
DB_USER=wordpress
# docker-compose.yml
db:
image: mysql:${DB_VERSION}
environment:
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
env_file:
- .env
覆盖环境变量
# 使用不同环境变量文件
docker-compose --env-file .env.prod up -d
# 直接设置环境变量
DB_PASSWORD=secret docker-compose up -d
9. 多环境配置
9.1. 开发环境配置
docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
environment:
- DEBUG=true
ports:
- "5000:5000"
9.2. 生产环境配置
docker-compose.prod.yml
version: '3.8'
services:
app:
image: myregistry/myapp:latest
environment:
- DEBUG=false
- DB_HOST=prod.db.example.com
restart: always
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
9.3. 使用方式
# 开发环境
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# 生产环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml -p prod up -d
10. 健康检查配置
10.1. 基本健康检查
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
10.2. 高级健康检查
services:
db:
image: mysql:5.7
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
interval: 5s
timeout: 10s
retries: 10
10.3. 依赖健康检查
services:
app:
image: myapp
depends_on:
db:
condition: service_healthy
redis:
condition: service_started # 只需要启动,不需要健康
11. 实战案例:多容器Web应用部署
11.1. 项目结构
myproject/
├── docker-compose.yml
├── Dockerfile
├── app/
│ ├── __init__.py
│ ├── app.py
│ └── requirements.txt
└── nginx/
└── nginx.conf
11.2. 应用代码
app.py
from flask import Flask, jsonify
import os
import redis
import time
app = Flask(__name__)
# 从环境变量获取配置
REDIS_HOST = os.getenv('REDIS_HOST', 'redis')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
# 连接Redis
cache = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
@app.route('/')
def hello():
count = cache.incr('hits')
return jsonify(hello='world', visitor_count=count)
@app.route('/time')
def current_time():
return jsonify(time=time.ctime())
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000)
11.3. Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY ./app/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app .
CMD ["flask", "run", "--host=0.0.0.0"]
11.4. Nginx配置
nginx.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
11.5. Docker Compose配置
docker-compose.yml
version: '3.8'
services:
app:
build: .
restart: always
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
depends_on:
- redis
networks:
- appnet
redis:
image: redis:alpine
restart: always
volumes:
- redis_data:/data
networks:
- appnet
command: redis-server --appendonly yes
nginx:
image: nginx:alpine
restart: always
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- appnet
volumes:
redis_data:
networks:
appnet:
driver: bridge
11.6. 部署步骤
克隆项目或创建上述文件结构
构建并启动服务:
docker-compose up -d --build
验证服务:
curl http://localhost
查看日志:
docker-compose logs -f
停止服务:
docker-compose down
12. 最佳实践
版本控制:始终使用特定版本的Docker镜像
image: redis:6.2-alpine # 而不是 redis:latest
安全配置:
使用非root用户运行容器
通过env_file管理敏感信息
限制容器资源
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
可维护性:
为服务添加健康检查
使用restart策略
添加元数据标签
labels:
com.example.description: "Web application service"
环境隔离:
使用不同项目名称(-p参数)
为不同环境创建不同的compose文件
日志管理:
配置日志驱动
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "3"
性能优化:
使用多阶段构建减小镜像体积
合理使用数据卷
避免不必要的依赖
13. 总结
Docker Compose是容器化应用开发、测试和部署的强大工具,通过本文的详细介绍,您应该已经掌握了:
Docker Compose的核心概念和安装方法
docker-compose.yml文件的编写技巧和完整指令集
从单容器到多容器应用的部署流程
网络配置和数据卷管理的高级用法
环境变量和多环境配置策略
健康检查和依赖关系配置
实际项目部署的完整案例
生产环境最佳实践
Docker Compose通过声明式配置显著简化了容器编排工作,特别适合开发团队快速搭建一致的开发、测试环境,也为生产环境的微服务部署提供了标准化方案。随着对Docker生态的深入探索,您可以将Compose与Docker Swarm、Kubernetes等工具结合使用,构建更复杂的分布式系统。
要持续提升Docker Compose技能,建议:
定期查阅[Docker官方文档](https://docs.docker.com/compose/)
尝试将现有项目容器化
探索Docker Compose与CI/CD工具的集成
研究Docker Stack(Swarm模式下的Compose)
通过不断实践和深入理解容器化技术,您将能够构建更健壮、可扩展的现代化应用架构。





