Docker Compose(容器编排)使用指南
- 什么是 Docker Compose
- 为什么要 Docker Compose
- Docker Compose 的功能
- Docker Compose 文件
- Docker Compose 文件的基本结构
- Docker Compose 常用指令
- Docker Compose 命令
- Docker Compose 实验:图书管理系统容器化编排
什么是 Docker Compose
docker-compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过使用 YAML 文件来配置应用程序的服务,用户可以使用单个命令来创建和启动所有服务,从而便利的管理复杂的应用程序架构。
docker-compose 中有两个非常重要的概念:
- 服务(Service):服务是指在 Docker Compose 文件中定义的一个容器实例。每个服务通常对应于一个应用程序组件,例如数据库、缓存服务器或 Web 服务器。服务定义了容器的镜像、环境变量、端口映射、卷挂载等配置。
- 项目(Project):项目是由一组相关的服务组成的集合。每个项目都有一个唯一的名称,通常是 Docker Compose 文件所在目录的名称。项目名称用于区分不同的应用程序实例,确保同一主机上可以运行多个独立的应用程序。项目默认是在 docker-compose.yml 文件中构建的,整个项目的生命周期由 Docker Compose 工具进行管理。
因此,通过 compose 可以方便管理多个服务实例,简化开发和部署流程。

docker compose 就像一艘航母一样,有舰载机、防空导弹,这些也就是一个个的容器,彼此之间通过网络进行通信和协作,共同完成复杂的应用程序功能。
为什么要 Docker Compose
在微服务架构中,应用程序通常由多个独立的服务组成,每个服务都运行在自己的容器中。管理这些容器的生命周期、网络和存储等配置变得非常复杂。Docker Compose 提供了一种简单的方式来定义和管理这些多容器应用程序。
使用 Docker Compose 的主要优点包括:
- 简化配置:通过 YAML 文件集中管理所有服务的配置,避免了手动配置每个容器的繁琐过程。
- 一致性:确保在不同环境(如开发、测试和生产)中使用相同的配置,减少了环境差异带来的问题。
- 易于扩展:可以轻松添加、删除或修改服务,支持快速迭代和开发。
- 集中管理:通过一个命令(如
docker-compose up)启动或停止整个应用程序,简化了操作流程。 - 自定义服务启动顺序:可以通过配置文件指定服务的启动顺序,确保依赖关系正确处理。若通过手动部署,可能会因为服务启动顺序不合理导致服务启动失败。
使用 docker compose,可以大大提高开发和运维的效率,特别是在处理复杂的多容器应用程序时。毕竟,你也不想每次都手动启动和停止一个个的容器吧。
Docker Compose 的功能
使用 docker-compose.yml(默认是这个文件)来定义应用程序的服务和配置。然后,通过以下命令来管理应用程序的生命周期:
- 启动服务:使用
docker-compose up命令启动所有服务。 - 停止服务:使用
docker-compose down命令停止所有服务并清理资源。 - 查看日志:使用
docker-compose logs命令查看所有服务的日志输出。 - 执行命令:使用
docker-compose exec命令在指定服务的容器中执行命令。
Docker Compose 文件
目前官方支持两个大版本,Version 2 和 Version 3。Version 3 是目前推荐使用的版本,支持更多的功能和特性,Version 1 已经不再维护。下面对该文件的讲解基于 Version 3。
Docker Compose 文件的基本结构
docker-compose.yml 文件是 Docker Compose 的核心配置文件,它描述了应用需要的服务、网络、卷等。一个典型的 Compose 文件包含以下层次结构:
services:定义应用中的服务,每个服务相当于一个容器的配置。volumes(可选):定义数据卷,方便服务之间共享数据或持久化存储。networks(可选):定义网络,让服务之间通信。
模板示例
services:
web: # 定义一个名为 web 的服务
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- mynet
db: # 定义一个名为 db 的服务
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
volumes:
- db_data:/var/lib/mysql
networks:
- mynet
volumes:
db_data: {} # 定义持久化存储卷
networks:
mynet: {} # 定义一个网络
这个模板展示了最常见的结构:一个前端 nginx 和一个后端 mysql 数据库,共享网络 mynet,数据库还使用了持久化卷 db_data。
Docker Compose 常用指令
说明:以下示例均为
docker-compose.yml部分片段;
1) version(可选,Compose V2 起通常省略)
指定 Compose 文件语法版本。V2 起推荐省略,保留也不影响使用。
services:
app:
image: alpine
command: echo "hello"
2) services
定义服务(容器)。键名就是服务名。
services:
web:
image: nginx:alpine
3) image
指定使用的镜像(支持 name:tag)。
services:
web:
image: nginx:1.27-alpine
4) build
从 Dockerfile 构建镜像。可用简写或展开配置。
services:
api:
build: ./api # 简写:context=./api,Dockerfile 默认名
展开写法(更灵活:自定义 Dockerfile、构建参数等):
services:
api:
build:
context: ./api
dockerfile: Dockerfile.dev
target: runtime
args:
APP_ENV: production
5) command
覆盖镜像中的 CMD(或作为 entrypoint 的参数)。支持字符串或数组。
services:
job:
image: python:3.12-slim
command: ["python", "main.py", "--once"]
6) entrypoint
覆盖镜像中的 ENTRYPOINT。常用于把容器入口固定为脚本。
services:
worker:
image: node:20-alpine
entrypoint: ["node", "worker.js"]
command: ["--concurrency=4"] # 作为 entrypoint 的参数
小贴士:优先级为
entrypoint>CMD。两者都写时,command会作为entrypoint的参数。
7) ports
将容器端口映射到宿主机。格式:HOST:CONTAINER。
services:
web:
image: nginx
ports:
- "8080:80" # 宿主机 8080 -> 容器 80
8) expose
仅在 Compose 网络内暴露端口,不映射到宿主机(供同网络下其他服务访问)。
services:
web:
image: nginx
expose:
- "80" # 仅服务间可见,不对宿主机开放
对比:
ports=对外映射;expose=仅对内可见。
9) environment
设置环境变量(键值或从变量继承)。
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: appdb
10) env_file
从文件批量加载环境变量(常配合 .env)。
services:
api:
image: my/api:latest
env_file:
- .env
- ./config/api.env
文件内容示例:
PORT=3000 LOG_LEVEL=info
11) volumes
挂载数据卷/目录(持久化或共享数据)。
services:
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata: {}
12) networks
指定服务加入的网络(隔离与互通)。
services:
web:
image: nginx
networks: [appnet]
api:
image: my/api
networks: [appnet]
networks:
appnet: {}
13) healthcheck
为服务定义健康检查,供 depends_on 的 service_healthy 条件使用。
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -proot || exit 1"]
interval: 10s
timeout: 3s
retries: 5
start_period: 20s
关键字段:
test:检查命令(数组或字符串)。返回 0 视为健康。interval:检查间隔。timeout:单次检查超时。retries:连续失败次数达到后视为不健康。start_period:启动宽限期(在此期间失败不计入retries)。
14) depends_on(支持健康状态条件)
声明启动/依赖顺序。结合 healthcheck 可等待依赖服务变为健康后再启动。
services:
web:
image: nginx:alpine
depends_on:
db:
condition: service_healthy # 等 db 健康后再启动 web
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -proot || exit 1"]
interval: 10s
timeout: 3s
retries: 5
start_period: 20s
condition可选值:
service_started:依赖服务启动即满足(默认行为)。service_healthy:依赖服务健康才满足(需配置healthcheck)。
Docker Compose 命令
Docker Compose 提供了丰富的命令用于管理多容器应用。整体上,这些命令与前面学习的 Docker 容器、镜像操作类似,因此只需掌握常用的即可。
常用命令一览表
| 命令 | 功能说明 |
|---|---|
docker compose up |
根据 docker-compose.yml 启动服务(若无镜像则自动构建/拉取)。 |
docker compose down |
停止并删除由 up 创建的容器、网络、卷。 |
docker compose start |
启动已经存在的服务容器(不会新建)。 |
docker compose stop |
停止服务容器但不删除。 |
docker compose restart |
重启服务容器。 |
docker compose ps |
查看 Compose 管理的容器列表及状态。 |
docker compose logs |
查看服务容器的日志。 |
docker compose run |
运行一次性容器(类似 docker run)。 |
docker compose exec |
在正在运行的服务容器中执行命令。 |
docker compose build |
构建或重新构建服务镜像。 |
docker compose pull |
拉取服务镜像。 |
docker compose config |
验证并输出最终的 Compose 配置。 |
docker compose top |
查看服务容器的进程信息。 |
docker compose events |
查看容器事件流。 |
重点命令详解
1. docker compose up
功能:根据
docker-compose.yml文件启动服务。特点:
- 如果镜像不存在,会自动构建或拉取。
- 默认在前台运行(可加
-d参数后台运行)。
示例:
docker compose up -d
后台启动所有服务。
2. docker compose down
功能:停止并删除由
up创建的容器、网络、卷(默认卷会被删除,挂载的命名卷不会删)。常用参数:
-v:删除匿名卷。--rmi all:删除所有镜像。
示例:
docker compose down -v
停止服务并删除匿名卷。
3. docker compose run
功能:运行一次性容器,适合执行单独任务,不影响已有服务。
与
up区别:up是启动整个应用。run是基于某个服务镜像临时起一个容器。
示例:
docker compose run web echo "hello"
在 web 服务容器里执行 echo "hello",执行完成后容器会退出。
Docker Compose 实验:图书管理系统容器化编排
本实验将一个基于 Spring Boot 的图书管理系统,通过 Docker Compose 进行多容器编排,实现前端 Nginx、后端 Spring Boot 服务以及 MySQL 数据库的协同运行。
1. 系统结构
实验系统由三个主要服务组成:
| 服务名称 | 镜像 | 端口 | 功能说明 |
|---|---|---|---|
| web | nginx:stable-alpine3.21-perl | 8110 | 反向代理前端请求,转发到后端 Spring Boot |
| backservice | openjdk:24-jdk | 8080 | Spring Boot 后端服务 |
| mysql | mysql:8.0.41 | 3306 | 数据存储,图书信息及用户信息 |
各服务通过自定义网络 mylibnet 互相通信。
2. Spring Boot 配置
在 application.properties 中设置数据库连接与 MyBatis 配置:
spring.application.name=demo
spring.datasource.url=jdbc:mysql://mysql:3306/lib_manage?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=ljx@docker
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatis 配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.demo.model
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
注意:
allowPublicKeyRetrieval=true用于解决 MySQL 8.0 默认caching_sha2_password的认证问题。
3. Docker Compose 文件
创建 lib_services.yml 文件:
version: "3.9"
services:
web:
image: nginx:stable-alpine3.21-perl
ports:
- "8110:80"
networks:
- mylibnet
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
backservice:
condition: service_started
backservice:
image: openjdk:24-jdk
depends_on:
- mysql
command: java -jar /app/demo-0.0.1-SNAPSHOT.jar
volumes:
- ./app/:/app/
networks:
- mylibnet
mysql:
image: mysql:8.0.41
environment:
MYSQL_ROOT_PASSWORD: "ljx@docker"
networks:
- mylibnet
volumes:
- ./mysql/varlib/:/var/lib/mysql
healthcheck:
test:
[
"CMD",
"mysql",
"--user=root",
"--password=ljx@docker",
"-e",
"SELECT 1;",
]
interval: 10s
timeout: 5s
retries: 10
networks:
mylibnet:
driver: bridge
4. Nginx 配置
在 nginx/conf.d/default.conf 中,将请求转发到后端 Spring Boot 服务:
server {
listen 80;
access_log off;
location / {
proxy_pass http://backservice:8080/;
}
}
5. 启动容器
在 lib_services.yml 所在目录执行:
docker compose up -d
-d:后台运行容器。- 查看日志:
docker compose logs -f backservice
- 停止并移除容器:
docker compose down
6. 数据库初始化
如果有初始 SQL 文件,可将 .sql 文件放在 mysql 目录下,然后在容器启动后导入:
docker exec -i lib-mysql-1 mysql -uroot -pljx@docker lib_manage < init.sql
7. 实验效果
- 打开浏览器访问
http://[server_ip]:8110/
可以看到系统主页,通过 Nginx 访问 Spring Boot 服务。 - 数据库通过 MySQL 容器提供服务,并持久化存储在本地
./mysql/varlib/。
通过 Docker Compose,本实验实现了图书管理系统的前后端分离 + 数据库独立部署,容器间通过自定义网络通信,整个系统可以快速启动、停止和迁移。