目录
1. Docker Compose是什么?
2. 为什么需要Docker Compose?
3. 安装Docker Compose
4. YAML语法基础
5. docker-compose.yml文件详解
6. Docker Compose常用命令
7. 实战案例:从简单到复杂
8. 服务间通信
9. 数据持久化
10. 环境变量管理
11. 多环境部署
12. 最佳实践
13. 常见问题与解决方案
总结
Docker Compose 是一个用于定义和运行多容器Docker应用程序的工具。
形象比喻:
# 一个命令启动整个应用栈
docker-compose up
# 而不是一个个地启动:
docker run -d --name db mysql:8.0
docker run -d --name web --link db nginx
docker run -d --name app --link db --link web myapp
# 启动数据库
docker run -d \
--name mysql_db \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=myapp \
-v mysql_data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0
# 启动Redis
docker run -d \
--name redis_cache \
-p 6379:6379 \
redis:7-alpine
# 启动应用
docker run -d \
--name my_app \
--link mysql_db:db \
--link redis_cache:redis \
-e DATABASE_URL=mysql://root:123456@db:3306/myapp \
-e REDIS_URL=redis://redis:6379 \
-p 8080:8080 \
my-spring-app:latest
# docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7-alpine
app:
image: my-spring-app:latest
ports:
- "8080:8080"
environment:
DATABASE_URL: mysql://root:123456@db:3306/myapp
REDIS_URL: redis://redis:6379
depends_on:
- db
- redis
volumes:
mysql_data:
一个命令搞定:
docker-compose up -d
特性 | 传统Docker命令 | Docker Compose |
---|---|---|
启动复杂度 | 需要多个长命令 | 一个命令 |
配置管理 | 分散在各个命令中 | 集中在YAML文件 |
服务依赖 | 手动管理启动顺序 | 自动处理依赖 |
网络配置 | 手动创建和连接 | 自动创建 |
数据卷管理 | 分别创建 | 统一管理 |
环境一致性 | 容易出错 | 配置文件保证一致性 |
docker-compose --version
# 或者新版本语法
docker compose version
Docker Desktop已经包含了Docker Compose,无需单独安装。
# 安装pip
sudo apt update
sudo apt install python3-pip
# 安装docker-compose
pip3 install docker-compose
# 验证安装
docker-compose --version
# 下载最新版本
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
# Ubuntu/Debian
sudo apt update
sudo apt install docker-compose
# CentOS/RHEL
sudo yum install docker-compose
YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化标准。
# 正确的缩进(使用空格,不要用Tab)
services:
web:
image: nginx
ports:
- "80:80"
# 错误的缩进
services:
web:
image: nginx
ports:
- "80:80"
# 正确
key: value
# 错误
key:value
# 列表语法
fruits:
- apple
- banana
- orange
# 或者内联形式
fruits: [apple, banana, orange]
# 这些都是有效的
name: John
name: "John"
name: 'John'
# 特殊字符需要引号
message: "Hello: World"
path: "C:\\Users\\Name"
# 布尔值
enabled: true
disabled: false
# 数字
port: 8080
pi: 3.14
version: '3.8' # 版本号
services: # 服务定义
service1:
# 服务1配置
service2:
# 服务2配置
volumes: # 数据卷定义
volume1:
networks: # 网络定义
network1:
version: '3.8' # Compose文件格式版本
services: # 定义服务
web: # 服务名称
# 服务配置
db:
# 数据库配置
volumes: # 定义数据卷
data: # 数据卷名称
networks: # 定义网络
frontend: # 网络名称
backend:
configs: # 定义配置文件(可选)
secrets: # 定义敏感数据(可选)
Compose文件版本 | Docker Engine版本 |
---|---|
3.8 | 19.03.0+ |
3.7 | 18.06.0+ |
3.6 | 18.02.0+ |
3.0-3.5 | 17.06.0+ |
version: '3.8' # 推荐
services:
web:
image: nginx:latest # 使用的镜像
container_name: my-nginx # 容器名称(可选)
ports: # 端口映射
- "8080:80" # 主机端口:容器端口
- "8443:443"
environment: # 环境变量
- ENV=production
- DEBUG=false
volumes: # 数据卷挂载
- ./html:/usr/share/nginx/html
- ./config:/etc/nginx/conf.d
networks: # 网络配置
- frontend
depends_on: # 依赖关系
- db
restart: unless-stopped # 重启策略
services:
app:
build: # 构建配置
context: . # 构建上下文路径
dockerfile: Dockerfile # Dockerfile文件名
args: # 构建参数
JAR_FILE: app.jar
VERSION: 1.0.0
image: my-app:latest # 构建后的镜像名
services:
app:
image: my-app:latest
deploy: # 部署配置(Swarm模式)
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
healthcheck: # 健康检查
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging: # 日志配置
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
db:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql # 使用命名卷
volumes:
mysql_data: # 定义命名卷
driver: local # 卷驱动
services:
web:
image: nginx
volumes:
- ./html:/usr/share/nginx/html:ro # 只读挂载
- ./logs:/var/log/nginx # 读写挂载
- /etc/localtime:/etc/localtime:ro # 同步时间
volumes:
mysql_data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.100,rw
device: ":/path/to/dir"
app_data:
external: true # 使用外部卷
name: my-app-data # 外部卷名称
services:
web:
networks:
- frontend
app:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
driver: bridge # 网络驱动
backend:
driver: bridge
internal: true # 内部网络,不能访问外网
networks:
custom:
driver: bridge
ipam: # IP地址管理
config:
-