目录
- [引言:为什么你需要 Docker Compose?](#引言:为什么你需要 Docker Compose?)
- 手动部署项目
- [什么是 docker compose](#什么是 docker compose)
-
- [compose 顶级元素](#compose 顶级元素)
- compose.yaml
- 关键信息解读
-
- [1. **`services: mysql` (MySQL 服务)**](#1.
services: mysql(MySQL 服务)) - [2. **`services: wordpress` (WordPress 服务)**](#2.
services: wordpress(WordPress 服务)) - [3. **顶级元素 `volumes` 和 `networks`**](#3. 顶级元素
volumes和networks)
- [1. **`services: mysql` (MySQL 服务)**](#1.
- 核心命令:管理你的应用栈
- 总结

引言:为什么你需要 Docker Compose?
经过上面几篇博客的内容,我们已经对 Docker 有了初步的认知。但在现实应用中,一个应用往往会使用多个镜像文件,本博文我们以一个简单的博客系统为例,需要一个应用服务(如 WordPress)和一个数据库服务(如 MySQL)。
因此,完整流程来说,我们需要:
- 先创建一个共享网络
- 启动 MySQL 容器,配置好密码、数据库名、数据卷、网络等
- 启动 WordPress 容器,配置好端口、数据库连接信息,并连接到同一个网络
- 确保 WordPress 在 MySQL 启动之后再启动
本博文,我们将首先使用之前博文阐述的方法,通过 docker run 命令手动部署应用。然后我们讨论为什么在正式项目中不推荐使用手动部署方式,以及建议的 docker compose 方案及其原因。最后通过 docker compose 方案部署应用。
手动部署项目
明确下,我们将要部署的 WordPress 博客系统需要 wordpress 应用 和 mysql 数据库。
-
创建网络: 确保两个容器可以互相通信。
bashdocker network create blog -
启动 MySQL 容器:
bashdocker run -d -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -e MYSQL_DATABASE=wordpress \ -v mysql-data:/var/lib/mysql \ -v /app/myconf:/etc/mysql/conf.d \ --restart always --name mysql \ --network blog \ mysql:8.0 -
启动 WordPress 容器:
bashdocker run -d -p 8080:80 \ -e WORDPRESS_DB_HOST=mysql \ -e WORDPRESS_DB_USER=root \ -e WORDPRESS_DB_PASSWORD=123456 \ -e WORDPRESS_DB_NAME=wordpress \ -v wordpress:/var/www/html \ --restart always --name wordpress-app \ --network blog \ wordpress:latest
完成上述步骤后,用户即可在 localhost:8080 查看到博客首页。但是回头来看,这个过程不仅繁琐,而且难以维护。不管是我们每次部署、迁移或交付给同事,或是修改一个端口、环境变量,可能就需要完整重复上述所有命令行所有步骤。都需要依赖一长串的 docker run 命令和手动步骤,这不仅效率低下,而且极易出错。
Docker Compose 正是为此而生。
什么是 docker compose
根据 Docker 官方文档的定义:
Compose是一个用于定义和运行多容器 Docker 应用程序的工具。通过Compose,您可以使用一个YAML文件来配置应用程序的服务。然后,使用一个命令,就可以从您的配置中创建并启动所有服务。
简而言之,Compose 允许我们将复杂的多容器应用"编排"在一个文件里,实现"一处定义,处处运行",真正做到事半功倍。
compose 顶级元素
Docker Compose 的魔力在于其核心的 compose.yaml 文件,它使用 YAML 语法来定义应用的蓝图。
我们先来看一下 Compose 文件的几个顶级元素(根据 Docker 官方文档):
services: 定义应用包含的各个容器networks: 定义服务可以加入的网络volumes: 定义服务可以使用的数据卷 ,用于数据持久化configs: 用于存储非敏感的配置信息secrets: 用于存储敏感信息,如密码name: 定义此项目的名称
compose.yaml
现在,我们将上面手动的部署步骤,转换为一个 compose.yaml 文件:
yaml
# 定义项目名称
name: myblog
# 定义所有服务
services:
# MySQL 服务
mysql:
container_name: mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
# WordPress 服务
wordpress:
container_name: wordpress-app # 自定义容器名称
image: wordpress:latest # 使用最新版的 wordpress 镜像
ports:
- "8080:80" # 映射宿主机的 8080 端口到容器的 80 端口
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=123456
- WORDPRESS_DB_NAME=wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on: # 依赖关系
- mysql
# 统一定义数据卷
volumes:
mysql-data:
wordpress:
# 统一定义网络
networks:
blog:
关键信息解读
让我们深入分析上述 YAML 文件中的关键配置,并对照官方 Docker Hub 的说明来理解它们的含义。
1. services: mysql (MySQL 服务)
image: mysql:8.0:指定使用 MySQL 官方镜像的 8.0 版本。ports: "3306:3306" :将宿主机 的 3306 端口映射到容器的 3306 端口,以便外部工具可以连接数据库。environment:这是配置 MySQL 容器的核心 。 根据 MySQL 官方文档:MYSQL_ROOT_PASSWORD=123456:(必需) 设置 MySQL 'root' 用户的密码。MYSQL_DATABASE=wordpress:(可选) 这会在容器启动时自动创建一个名为 wordpress 的数据库。
volumes: 这是数据持久化的关键 。mysql-data:/var/lib/mysql:将 Docker 管理的命名卷 mysql-data 通过卷映射到容器内的 /var/lib/mysql 目录。这是 MySQL 存储所有数据的地方。如果不映射,容器删除后所有数据库数据都会丢失。/app/myconf:/etc/mysql/conf.d:将宿主机的 /app/myconf 目录(你需要自己创建并放入 conf.d 文件)挂载到容器内,用于自定义 MySQL 配置。networks: "blog":将此服务连接到我们定义的 blog 网络。
2. services: wordpress (WordPress 服务)
image: wordpress:latest: 指定使用 WordPress 官方镜像 的 latest 版本。ports: "8080:80": 将宿主机的 8080 端口映射到容器的 80 端口(WordPress 默认运行在 80 端口)。environment: 这是配置 WordPress 连接数据库的核心 。 根据 WordPress 官方文档:WORDPRESS_DB_HOST=mysql:(必需) 数据库主机名。这里我们填写 mysql,即我们在 Compose 中定义的 MySQL 服务名。Compose 提供了内置的 DNS 解析,wordpress 容器可以通过服务名 mysql 找到 MySQL 容器。WORDPRESS_DB_USER=root:(必需) 数据库用户名。WORDPRESS_DB_PASSWORD=123456:(必需) 数据库密码(必须与 MYSQL_ROOT_PASSWORD 一致)。WORDPRESS_DB_NAME=wordpress:(可选) 要使用的数据库名称(必须与 MYSQL_DATABASE 中创建的库名一致)。
volumes:wordpress:/var/www/html:将 Docker 命名卷 wordpress 通过卷映射 到容器的 /var/www/html 目录。这是 WordPress 存放其核心文件、主题、插件和上传内容的地方。同样,这是保证网站数据不丢失的必需配置。
depends_on: "mysql": 这是服务编排的关键。 它告诉 Compose,wordpress 服务依赖于 mysql 服务。在启动时,Compose 会确保 mysql 容器启动后,再去启动 wordpress 容器,避免了 WordPress 启动时因找不到数据库而报错。
3. 顶级元素 volumes 和 networks
volumes: { mysql-data:, wordpress: }: 在这里声明我们在服务中使用的"卷映射"。这让 Docker 来管理这些卷的生命周期。networks: { blog: }: 声明我们要创建的 blog 网络。如果不声明,Compose 会自动创建一个默认网络。
核心命令:管理你的应用栈
现在,我们有了一个 compose.yaml 文件。我们不再需要长串的 docker run 命令,只需要在compose.yaml 文件所在的目录中执行几个简单的 docker compose 命令。
批量上线(创建并启动)
bash
# -d 表示 "detached",即在后台运行
docker compose up -d
执行此命令,Compose 会:
- 读取
compose.yaml文件。 - 创建
blog网络(如果不存在)。 - 创建
mysql-data和wordpress卷(如果不存在)。 - 拉取
mysql:8.0和wordpress:latest镜像(如果本地没有)。 - 创建并启动
mysql容器。 - 等待
mysql启动后,创建并启动wordpress容器。
批量下线(停止并移除)
bash
docker compose down
此命令会停止并移除 mysql 和 wordpress 容器,并移除 blog 网络。
注意: 默认情况下,docker compose down 会保留数据卷(Volumes)。这是 Docker 的安全机制,防止误删数据。但是,如果你想要彻底清理(下线并删除数据卷),包括数据库和 WordPress 的数据,可以修改 down 指令如下(不推荐):
bash
# -v (或 --volumes) 表示同时删除在 volumes 块中定义的命名卷
docker compose down -v
如果你还想删除服务使用到的镜像,可以使用 --rmi:
bash
# 删除所有服务使用的镜像
docker compose down --rmi all -v
修改更新应用
这是 Compose 最强大的功能之一。假设你修改了 compose.yaml 文件(例如,将 WordPress 的端口从 8080:80 改为 8081:80)。 你无需先执行 down。只需在更改配置后,再次运行:
bash
docker compose up -d
Compose 会自动进行比对与之前的 yaml 文件差别。它会发现 wordpress 服务的配置已更改,然后智能地停止、移除旧的 wordpress 容器,并用新配置创建一个新的容器。而 mysql 服务因为没有改动,会保持不动。
管理单个服务(启动/停止)
此外,你还可以对栈中的特定指定服务进行操作:
bash
# 停止 wordpress 服务
docker compose stop wordpress
# 启动已停止的 wordpress 服务
docker compose start wordpress
# 重启 mysql 服务
docker compose restart mysql
查看服务状态和日志
bash
# 查看当前 compose 栈中所有服务的运行状态
docker compose ps
# 实时查看 wordpress 服务的日志
docker compose logs -f wordpress
服务扩容(Scale)
注意:scale 命令不适用于定义了 container_name 的服务,且对于 WordPress 这种有状态应用扩容意义不大,但对于无状态 API 则非常有用
bash
# 假设我们有一个叫 api 的服务,将其扩容到 3 个实例
docker compose up --scale api=3 -d
总结
Docker Compose 是从"会用 Docker"到"善用 Docker"的进阶必备工具。它将复杂的、声明式的应用定义(compose.yaml)与简单的、命令式的操作(docker compose up/down)完美结合。
通过本文的 WordPress + MySQL 实例,我们看到 Compose 如何帮助我们:
- 声明式定义: 用一个 YAML 文件清晰描述整个应用栈。
- 易于管理: 使用
up,down,stop等简单命令管理整个应用的生命周期。 - 依赖管理: 通过
depends_on保证服务按正确顺序启动。 - 配置复用:
compose.yaml文件本身就是最好的文档,易于版本控制和团队共享。
现在,是时候把你那些散落的 docker run 命令,都统一到 compose.yaml 中了!
2025.11.1 西直门