05.Docker Compose

1. 为什么需要 Docker Compose

当你的应用需要多个容器协同工作时(比如 Web 应用 + 数据库 + 缓存),手动管理变得很痛苦:

1
2
3
4
5
# 手动管理多个容器的噩梦
docker network create myapp
docker run -d --name mysql --network myapp -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0
docker run -d --name redis --network myapp redis:alpine
docker run -d --name app --network myapp -p 3000:3000 -e DB_HOST=mysql -e REDIS_HOST=redis myapp

Docker Compose 让你用一个 YAML 文件定义和运行多容器应用,一条命令搞定一切。

2. Docker Compose 基础

安装

Docker Desktop 已内置 Docker Compose。Linux 用户如果单独安装 Docker Engine,Compose 插件已包含在内。

验证安装:

1
docker compose version

docker-compose.yml 基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 版本声明(可选,新版本可省略)
version: "3.8"

# 服务定义
services:
web:
image: nginx:alpine
ports:
- "80:80"

db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456

# 网络定义(可选)
networks:
default:
driver: bridge

# 数据卷定义(可选)
volumes:
db-data:

3. 核心配置项详解

services - 服务定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
services:
# 服务名称
app:
# 使用镜像
image: node:18-alpine

# 或者构建
build:
context: .
dockerfile: Dockerfile

# 容器名称
container_name: my-app

# 端口映射
ports:
- "3000:3000" # 宿主机端口:容器端口
- "3001:3001"

# 环境变量
environment:
- NODE_ENV=production
- DB_HOST=mysql
# 或从文件加载
env_file:
- .env

# 数据卷挂载
volumes:
- ./src:/app/src # 挂载目录
- node_modules:/app/node_modules # 命名卷

# 依赖关系
depends_on:
- mysql
- redis

# 重启策略
restart: unless-stopped

# 网络
networks:
- app-network

# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M

networks - 网络配置

1
2
3
4
5
6
7
8
9
10
11
12
services:
app:
networks:
- frontend
- backend

networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # 内部网络,无法访问外部

volumes - 数据卷

1
2
3
4
5
6
7
8
services:
mysql:
volumes:
- db-data:/var/lib/mysql

volumes:
db-data:
driver: local

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
version: "3.8"

services:
app:
build: .
container_name: my-app
ports:
- "3000:3000"
environment:
NODE_ENV: production
DB_HOST: mysql
DB_PORT: 3306
DB_NAME: myapp
REDIS_HOST: redis
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
volumes:
- ./logs:/app/logs
networks:
- app-network
restart: unless-stopped

mysql:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456}
MYSQL_DATABASE: myapp
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- app-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped

redis:
image: redis:7-alpine
container_name: redis-cache
volumes:
- redis-data:/data
networks:
- app-network
restart: unless-stopped

networks:
app-network:
driver: bridge

volumes:
mysql-data:
redis-data:

4. 常用命令

命令 说明
docker compose up 创建并启动所有服务
docker compose up -d 后台运行
docker compose down 停止并删除所有容器
docker compose down -v 同时删除数据卷
docker compose ps 查看服务状态
docker compose logs 查看日志
docker compose logs -f app 实时查看指定服务日志
docker compose exec app bash 进入容器
docker compose build 构建镜像
docker compose build --no-cache 不使用缓存构建
docker compose restart 重启所有服务
docker compose stop 停止服务(不删除)
docker compose start 启动已停止的服务
docker compose pull 拉取最新镜像