09-Docker Compose-一键启动多个服务
一个命令启动整个项目?
问题:一个完整的Web应用通常需要多个服务:
- Web服务器
- 数据库
- 缓存
- 消息队列
传统方式:
docker run -d --name web -p 80:80 nginx
docker run -d --name db -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0
docker run -d --name cache redis
...
Docker Compose方式:
docker-compose up -d
# 一键启动所有服务!
什么是Docker Compose?
定义:Docker Compose是用于定义和运行多容器Docker应用的工具。
特点:
- 使用YAML文件定义服务
- 一条命令启动/停止所有服务
- 自动创建和管理网络
- 服务之间通过名称互相访问
- 支持环境变量和配置文件
安装:
# Linux安装
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
# Docker Desktop自带
# Windows和Mac用户无需单独安装
验证安装:
docker-compose --version
docker-compose.yml基本结构
最简单的示例
version: '3.8'
services:
web:
image: nginx
ports:
- "80:80"
解释:
version:Compose文件版本services:定义服务web:服务名称image:使用的镜像ports:端口映射
完整示例
version: '3.8'
services:
web:
image: nginx:latest
container_name: my-web
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf
networks:
- app-network
environment:
- TZ=Asia/Shanghai
restart: unless-stopped
db:
image: mysql:8.0
container_name: my-db
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-network
restart: unless-stopped
cache:
image: redis:alpine
container_name: my-cache
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- app-network
restart: unless-stopped
networks:
app-network:
driver: bridge
volumes:
mysql-data:
redis-data:
常用配置项
1. image - 镜像
services:
web:
image: nginx:latest
app:
image: myapp:v1.0
2. build - 构建镜像
services:
app:
build: .
# 或
build:
context: .
dockerfile: Dockerfile
args:
VERSION: 1.0
3. ports - 端口映射
services:
web:
ports:
- "80:80" # 宿主机80映射到容器80
- "443:443"
- "8000-8010:8000-8010" # 端口范围
- "127.0.0.1:8080:80" # 只绑定localhost
4. volumes - 数据卷
services:
db:
volumes:
- db-data:/var/lib/mysql # 命名卷
- ./data:/data # 绑定挂载
- /etc/localtime:/etc/localtime:ro # 只读挂载
volumes:
db-data:
5. environment - 环境变量
services:
db:
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=mydb
# 或
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
6. env_file - 环境变量文件
services:
app:
env_file:
- .env
- .env.prod
.env文件内容:
MYSQL_ROOT_PASSWORD=123456
MYSQL_DATABASE=mydb
7. networks - 网络
services:
web:
networks:
- frontend
db:
networks:
- backend
networks:
frontend:
backend:
8. depends_on - 依赖关系
services:
web:
depends_on:
- db
- cache
db:
image: mysql:8.0
cache:
image: redis:alpine
注意:depends_on只控制启动顺序,不等待服务就绪。
9. restart - 重启策略
services:
web:
restart: always # 总是重启
# 或
restart: on-failure # 失败时重启
# 或
restart: unless-stopped # 除非手动停止
10. command - 覆盖启动命令
services:
app:
image: python:3.11
command: python -u app.py
# 或
command: ["python", "-u", "app.py"]
Docker Compose常用命令
启动服务
# 启动所有服务
docker-compose up
# 后台运行
docker-compose up -d
# 指定配置文件
docker-compose -f docker-compose.prod.yml up -d
# 启动特定服务
docker-compose up web db
停止服务
# 停止所有服务
docker-compose stop
# 停止特定服务
docker-compose stop web
重启服务
# 重启所有服务
docker-compose restart
# 重启特定服务
docker-compose restart web
删除服务
# 停止并删除所有容器、网络
docker-compose down
# 同时删除数据卷
docker-compose down -v
# 删除特定服务
docker-compose rm -f web
查看日志
# 查看所有服务日志
docker-compose logs
# 查看特定服务日志
docker-compose logs web
# 实时查看日志
docker-compose logs -f
# 查看最近N行
docker-compose logs --tail=100 web
# 查看最近N分钟的日志
docker-compose logs --since=10m web
查看状态
# 查看所有服务状态
docker-compose ps
# 查看服务详细信息
docker-compose config
进入容器
# 进入容器
docker-compose exec web bash
# 在容器内执行命令
docker-compose exec web ls /app
构建镜像
# 构建镜像
docker-compose build
# 构建特定服务镜像
docker-compose build web
# 构建时不使用缓存
docker-compose build --no-cache
实战1:Web应用+数据库
docker-compose.yml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- app
networks:
- app-network
app:
build: .
ports:
- "8000:8000"
environment:
- DB_HOST=db
- DB_NAME=mydb
- DB_USER=root
- DB_PASSWORD=123456
depends_on:
- db
networks:
- app-network
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: mydb
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-network
networks:
app-network:
volumes:
mysql-data:
使用
# 启动所有服务
docker-compose up -d
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止所有服务
docker-compose down
实战2:多环境配置
开发环境(docker-compose.yml)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- .:/app
environment:
- ENV=development
- DEBUG=true
command: python -u app.py
生产环境(docker-compose.prod.yml)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
environment:
- ENV=production
- DEBUG=false
command: gunicorn -w 4 -b 0.0.0.0:8000 app:app
restart: unless-stopped
使用
# 开发环境
docker-compose up -d
# 生产环境
docker-compose -f docker-compose.prod.yml up -d
实战3:微服务架构
version: '3.8'
services:
# API网关
gateway:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- user-service
- order-service
- product-service
networks:
- microservices
# 用户服务
user-service:
build: ./user-service
ports:
- "8001:8000"
environment:
- DB_HOST=user-db
- REDIS_HOST=cache
depends_on:
- user-db
- cache
networks:
- microservices
user-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE=users
volumes:
- user-db-data:/var/lib/mysql
networks:
- microservices
# 订单服务
order-service:
build: ./order-service
ports:
- "8002:8000"
environment:
- DB_HOST=order-db
- REDIS_HOST=cache
depends_on:
- order-db
- cache
networks:
- microservices
order-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE=orders
volumes:
- order-db-data:/var/lib/mysql
networks:
- microservices
# 商品服务
product-service:
build: ./product-service
ports:
- "8003:8000"
environment:
- DB_HOST=product-db
- REDIS_HOST=cache
depends_on:
- product-db
- cache
networks:
- microservices
product-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE=products
volumes:
- product-db-data:/var/lib/mysql
networks:
- microservices
# 缓存
cache:
image: redis:alpine
volumes:
- cache-data:/data
networks:
- microservices
networks:
microservices:
driver: bridge
volumes:
user-db-data:
order-db-data:
product-db-data:
cache-data:
健康检查
version: '3.8'
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
配置变量替换
version: '3.8'
services:
app:
image: myapp:${APP_VERSION:-latest}
environment:
- DB_HOST=${DB_HOST:-localhost}
- DB_PORT=${DB_PORT:-3306}
ports:
- "${APP_PORT:-8000}:8000"
.env文件:
APP_VERSION=v1.0
DB_HOST=db
DB_PORT=3306
APP_PORT=8000
最佳实践
1. 使用版本控制
version: '3.8' # 明确指定版本
2. 使用命名卷
volumes:
mysql-data: # 命名卷,便于管理
3. 使用自定义网络
networks:
app-network:
driver: bridge
4. 使用健康检查
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
5. 多环境配置
docker-compose.yml # 基础配置
docker-compose.dev.yml # 开发环境
docker-compose.prod.yml # 生产环境
本章小结
- Docker Compose:定义和管理多容器应用
- 配置文件:docker-compose.yml使用YAML格式
- 常用命令:up、down、logs、ps、exec
- 实战场景:Web应用、多环境、微服务
- 最佳实践:版本控制、命名卷、健康检查
现在已经掌握了Docker Compose,下一章我们来实战打包Python项目!
继续学下去,马上就能做实用项目了!