一、Docker Compose 是干什么的
简单理解:
Docker Compose 就是用一个 YAML 文件,把多个 Docker 容器一起定义、启动、停止和管理。
比如你的 Spring Cloud 项目可能有:
Nacos
MySQL
Redis
RabbitMQ
Gateway
System服务
Order服务
User服务
不用 Compose 的话,你可能需要一个个:
docker run ...
docker run ...
docker run ...
docker run ...
用了 Compose,只需要:
docker compose up -d
一次性启动。官方也是把 Compose 定位为管理多容器应用的工具。
二、最基本的 Compose 文件
现在推荐文件名:
compose.yaml
也支持:
compose.yml
docker-compose.yaml
docker-compose.yml
其中 compose.yaml 是现在推荐的名称。
最简单的例子:
services:
nginx:
image: nginx:latest
ports:
- "8080:80"
redis:
image: redis:7
目录:
docker-demo/
└── compose.yaml
进入目录:
cd docker-demo
启动:
docker compose up -d
查看:
docker compose ps
停止:
docker compose down
查看日志:
docker compose logs
这些都是 Compose 官方提供的核心生命周期命令。
三、核心结构
一个 Compose 文件你可以先记住这个结构:
services:
服务1:
image:
container_name:
ports:
volumes:
environment:
networks:
restart:
depends_on:
服务2:
image:
ports:
volumes:
networks:
volumes:
最重要的是:
services:
它下面定义的每一个东西,就是一个服务。
例如:
services:
mysql:
image: mysql:8.0
redis:
image: redis:7
nginx:
image: nginx:latest
这里实际上定义了三个服务:
mysql
redis
nginx
Compose 会根据这些配置创建对应的容器。服务之间可以通过 Docker 网络进行通信。
四、image
最常用的配置:
services:
redis:
image: redis:7
意思是:
使用 redis:7 镜像
创建 redis 服务
例如 MySQL:
services:
mysql:
image: mysql:8.0
RabbitMQ:
services:
rabbitmq:
image: rabbitmq:3-management
Nginx:
services:
nginx:
image: nginx:latest
五、container_name
可以指定容器名称:
services:
redis:
image: redis:7
container_name: teng-redis
启动以后:
docker ps
可以看到:
teng-redis
否则 Compose 默认会按照项目名、服务名等生成容器名称。
六、ports
这个非常重要。
ports:
- "8080:80"
格式:
宿主机端口:容器端口
所以:
ports:
- "8080:80"
表示:
Windows/Linux服务器
│
│ 8080
↓
Docker容器
│
│ 80
↓
Nginx
浏览器访问:
http://服务器IP:8080
实际访问容器里的:
80
例如 MySQL:
mysql:
image: mysql:8.0
ports:
- "3306:3306"
Redis:
redis:
image: redis:7
ports:
- "6379:6379"
Nacos:
nacos:
image: nacos/nacos-server
ports:
- "8848:8848"
七、environment
配置环境变量。
例如 MySQL:
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: teng_cloud
相当于告诉 MySQL:
root密码 = 123456
创建数据库 = teng_cloud
也可以写成:
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=teng_cloud
两种写法都可以。
我个人更推荐:
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: teng_cloud
可读性更好。
八、volumes
这个特别重要。
因为:
容器删除以后,容器里面的数据可能也没了。
所以数据库一般必须做数据持久化。
例如:
services:
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
这里:
mysql_data:/var/lib/mysql
表示:
Docker Volume
│
↓
mysql_data
│
↓
/var/lib/mysql
│
↓
MySQL容器
即使:
docker compose down
然后重新:
docker compose up -d
数据库数据仍然可以保留。
九、restart
生产环境非常常用:
restart: always
例如:
redis:
image: redis:7
restart: always
意思是容器异常退出或者 Docker 重启后,让 Docker 尽量自动重新启动这个容器。
常见:
restart: no
restart: always
restart: on-failure
restart: unless-stopped
生产服务器通常可以考虑:
restart: unless-stopped
十、networks
Compose 中非常重要。
例如:
services:
mysql:
image: mysql:8.0
networks:
- teng-network
redis:
image: redis:7
networks:
- teng-network
networks:
teng-network:
这样两个容器就在同一个 Docker 网络里面。
更重要的是:
容器之间不要使用 localhost 通信。
例如:
Spring Boot
↓
MySQL
Spring Boot 配置不能写:
localhost:3306
而应该写:
mysql:3306
因为:
services:
mysql:
image: mysql:8.0
这里的:
mysql
就是 Compose 网络里的服务名,可以作为主机名使用。
所以你的 Spring Boot:
spring:
datasource:
url: jdbc:mysql://mysql:3306/teng_cloud
Redis:
spring:
data:
redis:
host: redis
port: 6379
这是以后部署你的 Spring Cloud 项目时非常关键的一点。
十一、depends_on
例如:
services:
mysql:
image: mysql:8.0
system:
image: teng-system:1.0
depends_on:
- mysql
意思是:
system
↓
依赖
↓
mysql
Compose 会按照依赖关系创建/启动服务。
但是要注意:
depends_on:
- mysql
不代表 MySQL 已经完全可以接受业务连接。
它主要解决启动顺序问题。
如果需要等待 MySQL 真正健康,需要结合:
healthcheck:
十二、healthcheck
例如:
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"localhost",
"-uroot",
"-p123456"
]
interval: 10s
timeout: 5s
retries: 5
然后:
system:
image: teng-system:1.0
depends_on:
mysql:
condition: service_healthy
这样就比简单的:
depends_on:
- mysql
更加可靠。
十三、build
如果你不是直接使用 Docker Hub 镜像,而是自己的 Spring Boot 项目,可以:
services:
system:
build:
context: ./system
dockerfile: Dockerfile
意思是:
./system
↓
Dockerfile
↓
构建镜像
↓
启动容器
例如:
project
│
├── compose.yaml
│
├── gateway
│ └── Dockerfile
│
├── system
│ └── Dockerfile
│
└── order
└── Dockerfile
Compose:
services:
gateway:
build:
context: ./gateway
system:
build:
context: ./system
order:
build:
context: ./order
然后:
docker compose up -d --build
就可以重新构建并启动。
十四、一个完整的小案例
把前面的知识组合起来:
services:
mysql:
image: mysql:8.0
container_name: teng-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: teng_cloud
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- teng-network
redis:
image: redis:7
container_name: teng-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- teng-network
nginx:
image: nginx:latest
container_name: teng-nginx
restart: unless-stopped
ports:
- "80:80"
networks:
- teng-network
volumes:
mysql_data:
redis_data:
networks:
teng-network:
启动:
docker compose up -d
查看:
docker compose ps
看到:
teng-mysql
teng-redis
teng-nginx
查看日志:
docker compose logs
只看 MySQL:
docker compose logs mysql
实时看:
docker compose logs -f mysql
停止:
docker compose stop
重新启动:
docker compose start
删除容器和网络:
docker compose down
如果连 Volume 也删除:
docker compose down -v
这个 -v 要特别小心,生产数据库不要随便执行。
十五、你现在最应该记住的命令
| 命令 | 作用 |
|---|---|
docker compose up -d |
后台启动 |
docker compose up -d --build |
构建并启动 |
docker compose down |
停止并删除容器、网络 |
docker compose stop |
停止容器 |
docker compose start |
启动已经存在的容器 |
docker compose restart |
重启 |
docker compose ps |
查看状态 |
docker compose logs |
查看日志 |
docker compose logs -f |
实时日志 |
docker compose exec mysql bash |
进入 MySQL 容器 |
docker compose pull |
拉取镜像 |
docker compose build |
构建镜像 |
docker compose config |
检查/解析 Compose 配置 |
官方 CLI 目前提供了这些以及更多子命令。
十六、结合你现在的 Spring Cloud 项目
你现在如果准备把之前的项目部署到服务器,我建议最终结构可以做成:
Nginx
│
↓
Gateway
│
┌───────────┼───────────┐
↓ ↓ ↓
System Order User
│ │ │
└───────────┼───────────┘
↓
┌───────┴───────┐
↓ ↓
Redis MySQL
│
↓
RabbitMQ
Nacos
然后用一个:
compose.yaml
统一管理:
MySQL
Redis
RabbitMQ
Nacos
Nginx
Gateway
System
Order
User
...
官方完整 Compose 文档可以直接看:Docker Compose 官方文档