Docker Compose
🐳 Docker Compose
阅读原文 https://www.xiaozaoshu.top/articles/docker/compose
一、什么是 Docker Compose?
Docker Compose 是一个用于定义和运行多个 Docker 容器的工具。你只需用一个 docker-compose.yml
文件,描述好服务的配置,然后一条命令就可以启动整个系统。
适用场景:
- 需要运行多个服务(如 Web 服务 + 数据库 + 缓存)
- 希望用配置文件统一管理部署
- 开发、测试、部署环境一致性
二、安装 Docker Compose
1. 检查 Docker 是否已安装
docker -v
2. 检查 Docker Compose 是否集成(推荐使用 Docker Compose V2)
docker compose version
如果你看到版本号(如 Docker Compose version v2.27.1
),说明已安装。
3. 手动安装(Linux 下,如果未集成)
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \-o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
docker compose version
三、Docker Compose 文件结构详解(docker-compose.yml
)
一个典型的配置文件如下:
version: "3.9" # 指定Compose文件的语法版本services:# docker run -d --name redis -p 16379:6379 redis:7.2 redis-server --requirepass 1234@qwerredis:image: redis:7.2container_name: xiaozaoshu-redisports:- "16379:6379"
关键字段解释
字段 | 含义 |
---|---|
version | Compose 文件版本 |
services | 定义多个服务,每个服务类似一个 docker run 容器 |
image | 使用的镜像 |
build | 指定 Dockerfile 构建镜像 |
ports | 端口映射:宿主机:容器 |
volumes | 挂载卷(主机路径:容器路径) |
environment | 设置环境变量 |
depends_on | 设置服务间依赖关系 |
networks | 指定服务所属网络(用于服务间通信) |
version
Docker Compose 文件的 语法版本(Compose File Format),用于指定当前 YAML 文件使用的是哪一套规则。
Compose 文件的版本取决于你所使用的:
- Docker Engine 的版本
- Compose 的版本(V1 或 V2)
- 你需要使用的功能是否支持某个版本
Compose 版本历史速查
Version | 新增特性 |
---|---|
3.9 | 支持 init 字段(容器用 tini 初始化) |
3.8 | 支持 profiles 分组启动服务 |
3.7 | 支持 cpu_count 、cpu_percent |
3.4 ~ 3.6 | 添加 configs 、secrets (Swarm) |
2.4 | 支持 healthcheck.test 、depends_on.condition (V2 专属) |
- 查看
Docker
的版本命令docker version
- 查看
docker compose
的版本命令docker compose version
如果你使用的是 Docker Compose V2(Docker Desktop 2022+ 已默认内置),Compose V2 会自动使用当前 Docker
引擎支持的最新语法,无需手动指定。
建议
- 如果你使用的是 Docker Compose V2(大多数用户),可以 省略
version
。 - 如果你需要保持兼容性(比如部署在服务器上),建议使用
version: "3.9"
。
四、Docker Compose 常用命令速查表
命令 | 功能说明 | 示例 |
---|---|---|
docker compose up | 构建并启动所有服务 | docker compose up |
docker compose up -d | 后台运行(detach 模式) | ✅ 推荐用于开发 |
docker compose down | 停止并删除所有容器、网络、匿名卷 | docker compose down |
docker compose stop | 停止服务,但不删除容器 | docker compose stop |
docker compose start | 启动已停止的服务容器 | docker compose start |
docker compose restart | 重启所有服务 | docker compose restart |
docker compose build | 手动构建服务镜像 | docker compose build |
docker compose pull | 拉取最新镜像 | docker compose pull |
docker compose push | 推送镜像到远程仓库 | docker compose push |
docker compose ps | 查看服务容器状态 | docker compose ps |
docker compose logs | 查看日志 | docker compose logs redis |
docker compose logs -f | 实时追踪日志 | docker compose logs -f app |
docker compose exec | 在容器中执行命令(支持交互) | docker compose exec redis redis-cli |
docker compose run | 启动一个一次性容器运行命令 | docker compose run app npm install |
docker compose config | 查看合并后的配置(调试用) | docker compose config |
docker compose top | 查看容器的进程信息 | docker compose top |
docker compose up
执行此命令,Docker
会在当前目录下查找:
- docker-compose.yml(默认)
- 也支持 docker-compose.yaml(扩展名不同)
如果你用的是默认名称,上述命令就可以直接使用,无需任何参数。
你可以自定义文件名,比如 myapp-compose.yml
,然后使用 -f
指定:
docker compose -f myapp-compose.yml up
甚至可以组合多个文件:
docker compose -f docker-compose.yml -f docker-compose.override.yml up
这在区分开发 / 测试 / 生产环境时非常有用。
常见用法建议:
文件名 | 用途 |
---|---|
docker-compose.yml | 默认配置,推荐统一使用 |
docker-compose.override.yml | 默认自动合并(可选) |
docker-compose.prod.yml | 生产环境配置 |
docker-compose.dev.yml | 本地开发配置 |
docker-compose.test.yml | 测试环境配置 |
五、实战案例
示例:部署一个 Spring Boot + MySQL + Redis 应用
项目结构
xiaozaoshu/
├── docker-compose.yml
├── mysql/
│ └── init.d/
│ ├── 01_sys_config.sql
│ └── 02_sys_data.sql
├── app/
│ ├── Dockerfile
│ └── jar/
│ └── spring-demo.jar
app/Dockerfile
FROM openjdk:8-jdk-alpine
COPY jar/spring-demo.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose.yml
services:redis:image: redis:7.2container_name: xiaozaoshu-redisnetworks:- docker-backend-networkports:- "16379:6379"command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]# Nacos confignacos:image: xiaozaoshu-nacos:v1container_name: xiaozaoshu-nacosnetworks:- docker-backend-networkports:- "18848:8848"- "9848:9848"environment:- MODE=standalonevolumes:- ./nacos/data:/home/nacos/data # ✅ 数据.久化depends_on:- mysqlrestart: unless-stopped# MySQL configmysql:image: mysql:5.7container_name: xiaozaoshu-mysqlnetworks:- docker-backend-networkports:- "13306:3306"environment:- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # 从 .env 读取密码volumes:- ./mysql/data:/var/lib/mysql # 数据持久化- ./mysql/log:/var/log/mysql # 日志挂载- ./mysql/conf:/etc/mysql/conf.d # 自定义配置- ./mysql/init.d:/docker-entrypoint-initdb.d # 初始化脚本(*.sql) 脚本会按照文件名称排序后一次执行restart: unless-stoppedxiaozaoshu-system:image: xiaozaoshu-system-shanghai:v1container_name: xiaozaoshu-systemnetworks:- docker-backend-networkextra_hosts:- "test-xiaozaoshu.com.cn:192.168.2.100"ports:- "8181:8181"environment:NACOS_PASSWORD: 123@QweNACOS_HOST: test-xiaozaoshu.com.cnNACOS_PORT: 18848depends_on:- nacosentrypoint: ["/wait-for-nacos.sh"]command: ["java", "-jar", "app.jar"]restart: unless-stoppednetworks:docker-backend-network:external: true
由于 Docker 的 docker-entrypoint-initdb.d/ 目录中脚本是按照 文件名字典序(ASCII 排序) 自动执行的,需要通过 重命名文件
的方式来确保执行顺序。
启动项目
docker compose up -d
项目将自动启动:
- Spring Boot 应用运行在
test-xiaozaoshu.com.cn:8181
- MySQL 在
localhost:13306
- Redis 在
localhost:16379
六、进阶用法
1. .env
配置环境变量
可以写在 .env
文件中:
MYSQL_ROOT_PASSWORD=123456
然后在 compose 文件中使用:
environment:- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # 从 .env 读取密码
2. 多个 Compose 文件组合部署(如:测试环境)
docker compose -f docker-compose.yml -f docker-compose.test.yml up
3. 自动重启策略
restart: unless-stopped
七、常见问题排查
- 启动依赖问题
depends-on
只能保证顺序启动,不能保证nacos 已经可以启动完成可以正常提供服务了,所以增加了 wait-for-nacos.sh
,监测nacos服务的状态。
entrypoint: [“/wait-for-nacos.sh”, “java”, “-jar”, “app.jar”]
最初使用上述配置编写Dockerfile
,可能被忽略或合并不当,导致直接逃过了监测,直接启动应用,所以在镜像中不要定义默认的 ENTRYPOINT
,或 用 Compose 的 command
明确指定启动命令。
entrypoint: [“/wait-for-nacos.sh”]
command: [“java”, “-jar”, “app.jar”]
在 Linux 或 macOS 下,环境变量名称(即变量名)不能以点号 (.
) 开头,也不能包含点号,这是 POSIX 标准规定的。
- 环境变量名规则问题
- 只能包含:
字母
、数字
、下划线
(不能包含.
) - 必须以 字母或下划线 开头
- 变量名区分大小写
- 只能包含:
以下变量名是非法的:
nacos.password=abc # 错误:包含点号
正确做法(示例):
你可以用下划线 _
代替点号:
NACOS_PASSWORD: 1234qweR
Spring Boot 支持将 NACOS_PASSWORD
映射为配置属性 nacos.password
。
例如你可以在 Spring Boot 中这样读取:
nacos:password: ${NACOS_PASSWORD}
八、卸载 Docker Compose
如果是手动安装的,可以删除:
rm ~/.docker/cli-plugins/docker-compose
九、总结
优势 | 说明 |
---|---|
简洁 | 一份配置文件,统一管理多个服务 |
可移植 | docker-compose.yml 可轻松复制部署 |
跨平台 | 支持 Linux / Windows / macOS |
适合开发 | 快速启动开发环境,模拟微服务系统 |