Docker Compose:从单容器到多容器一键部署
本文系统介绍了 Docker Compose 的定义、语法、核心命令及实际应用。
通过对比传统的 docker run 启动方式与基于 Compose 的配置式管理,展示了 Compose 在多容器场景下的巨大优势——配置集中、自动化管理、高可移植性。
以 WordPress + MySQL 部署为例,文章详细讲解了如何从零编写 compose.yaml 文件并实现一键启动,帮助读者快速上手 Compose 的使用与实践。
介绍
定义
1、 Docker Compose 是 Docker 官方推出的多容器应用管理工具。
通过一个 YAML 文件(通常命名为 docker-compose.yml 或 compose.yaml),我们可以定义应用中所有服务的镜像、端口、卷、网络和环境变量,然后只需一条命令即可启动或停止整个系统。
2、在多容器场景下(例如 WordPress + MySQL),如果使用传统方式,需要:手动创建网络;为每个容器配置端口、环境变量、卷;严格控制启动顺序;每次更新或重启都要重复繁琐命令。
而 Docker Compose 只需:docker compose up -d 即可完成所有操作。
要理解 Docker Compose 的优势,我们可以通过对比传统单容器启动方式和 Compose 配置方式(下面展开)
安装
sudo apt-get update
sudo apt-get install docker-compose-plugin
# 或
sudo apt-get install docker-compose
验证安装(检查 Docker 版本):
docker --version
compose.yaml的语法
compose.yaml文件采用 YAML 语法,由多个顶级元素构成:
| 元素 | 作用 |
|---|---|
name | 定义项目名,用于隔离不同 Compose 项目的资源。 |
services | 定义容器服务(镜像、端口、环境变量、卷、网络等)。 |
volumes | 定义数据卷,用于持久化数据。 |
networks | 定义网络,用于服务间通信。 |
Docker Compose 的核心命令
| 命令 | 功能 | 说明 |
|---|---|---|
docker compose up -d | 启动所有服务 | 一键上线,自动创建网络、卷、容器。 |
docker compose down | 停止并删除容器 | 可加 --volumes 删除卷。 |
docker compose start | 启动停止的服务 | 不会重建容器。 |
docker compose stop | 停止运行的服务 | 保留容器和数据。 |
docker compose scale x2=3 | 扩容服务实例数 | 用于无状态服务扩展。 |
例子
我们以WordPress+MySQL 的部署场景为例,先详细说明传统单容器启动方式的操作和问题,再用 Docker Compose 进行改进,最后总结 Compose 的优势。
场景说明:
部署一个开源博客系统 WordPress,需要依赖 MySQL 数据库。两者需在同一网络中通信,且数据需要持久化(MySQL 数据、WordPress 文件)。传统方式需通过多条docker命令手动配置 。
一、传统单容器启动方式
1、创建自定义网络
docker network create blog # 创建名为blog的网络,用于两容器通信
mkdir -p /app/myconf #为目录挂载做准备
2、启动 MySQL 容器(数据库服务)
docker run -d \-p 3306:3306 \ # 宿主机3306端口映射到容器3306(MySQL默认端口)-e MYSQL_ROOT_PASSWORD=123456 \ # 数据库root密码-e MYSQL_DATABASE=wordpress \ # 初始化创建wordpress数据库-v mysql-data:/var/lib/mysql \ # 数据卷挂载,持久化MySQL数据-v /app/myconf:/etc/mysql/conf.d \ # 挂载自定义配置文件--restart always \ # 容器退出时自动重启--name mysql \ # 容器命名为mysql(供WordPress访问)--network blog \ # 加入blog网络mysql:8.0 # 使用MySQL 8.0镜像
该命令基于mysql:8.0镜像,创建并启动一个名为mysql的容器,核心目标是让 MySQL 服务稳定运行且数据不丢失,同时能被外部(如 WordPress)访问。
1、-d
2、-p 3306:3306
必要性:若需要从宿主机或其他机器访问容器内的 MySQL,必须配置端口映射;若仅容器间内部访问(如同一网络的 WordPress),可省略此参数。
3、-e MYSQL_ROOT_PASSWORD=123456
通过环境变量,设置 MySQL 的root用户密码为123456
注意:这是必填参数,若不设置,容器会启动失败;生产环境需使用更复杂的密码。
4、-e MYSQL_DATABASE=wordpress
功能:容器启动时,自动创建一个名为wordpress的数据库。
用途:避免手动进入容器创建数据库,适用于需要预设数据库的场景(如部署 WordPress 时)。
5、-v mysql-data:/var/lib/mysql
功能:将容器内存储数据的核心目录/var/lib/mysql,挂载到宿主机的数据卷mysql-data 上。
核心价值:实现数据持久化,即使容器被删除,数据仍保存在宿主机的数据卷中,下次启动新容器可复用数据。
6、-v /app/myconf:/etc/mysql/conf.d
功能:将宿主机/app/myconf目录,挂载到容器内的配置加载目录/etc/mysql/conf.d。
原理:MySQL 启动时会自动加载/etc/mysql/conf.d下所有.cnf结尾的文件,通过此挂载可自定义 MySQL 配置(如字符集、连接数等),无需修改镜像本身。
7、--restart always
功能:设置容器的重启策略为 “总是重启”。
场景:宿主机重启、容器意外崩溃时,MySQL 会自动恢复运行,保证服务可用性。
8、--name mysql
功能:给容器指定固定名称mysql。
用途:后续操作(如连接容器、查看日志)可直接用名称,无需记复杂的容器 ID;同时方便同一网络内的服务(如 WordPress)通过名称访问 MySQL。
9、--network blog
功能:将容器加入名为blog的自定义网络。
价值:同一网络内的服务(如 WordPress 容器)可通过 “容器名 + 端口” 直接通信,无需暴露宿主机端口,更安全。
10、mysql:8.0
功能:指定启动容器所使用的镜像,即MySQL 8.0版本。
注意:若不指定版本,默认拉取latest(最新版),生产环境建议固定版本,避免版本迭代导致兼容性问题。
在dockerhub.com上看到,在mysql容器内: 在/etc/mysql/conf.d目录下只要编写的文件是.cnf结尾,就会被当成配置文件(我们可以将之进行目录挂载) 对于mysql数据的存储,是放在/var/lib/mysql(我们可以将之进行数据持久化,即卷映射)
3、启动 WordPress 容器(博客系统)
docker run -d \-p 8080:80 \ # 宿主机8080端口映射到容器80(WordPress默认端口)-e WORDPRESS_DB_HOST=mysql \ # 数据库地址:通过容器名mysql访问(依赖blog网络)-e WORDPRESS_DB_USER=root \ # 数据库用户名-e WORDPRESS_DB_PASSWORD=123456 \ # 数据库密码(与MySQL一致)-e WORDPRESS_DB_NAME=wordpress \ # 数据库名(与MySQL创建的一致)-v wordpress:/var/www/html \ # 数据卷挂载,持久化WordPress文件--restart always \ # 自动重启--name wordpress-app \ # 容器命名为wordpress-app--network blog \ # 加入同一blog网络,与MySQL通信wordpress:latest # 使用最新版WordPress镜像
4、验证部署
宿主机访问http://localhost:8080,应显示 WordPress 初始化页面。 若能显示,证明通信成功

5、清理环境(如需重新部署)
docker rm -f mysql wordpress-app # 删除容器
docker network rm blog # 删除网络
docker volume rm mysql-data wordpress # 删除数据卷(谨慎:会丢失数据)
传统方式的问题
1、配置分散且复杂:
网络创建、MySQL 参数(密码、数据库名)、WordPress 参数(数据库地址、账号)、卷挂载路径等分散在 3 条核心命令中,后续修改或维护时需逐条查找,极易遗漏(比如忘记 MySQL 的密码与 WordPress 是否一致)。
2、依赖时序无保障: WordPress 必须依赖 MySQL 先启动,否则会因连接失败报错。
但传统方式中,若执行docker run时 MySQL 未就绪(如镜像拉取慢),WordPress 会启动失败,需手动重启。
3、重复操作冗余: 若需重新部署,需手动执行 “删除容器→删除网络→删除卷→重新创建网络→启动 MySQL→启动 WordPress” 等一系列步骤,步骤繁琐且易出错(比如漏删网络导致新容器无法加入)。
4、可移植性差: 若要在另一台机器部署,需手动复制所有命令,且需确保宿主机的/app/myconf目录存在(否则 MySQL 挂载失败),环境差异易导致部署失败。
二、基于 Docker Compose 的改进
核心思路
用compose.yaml文件集中定义所有资源(网络、MySQL、WordPress、数据卷),通过一条命令实现 “一键部署”“一键启停”,解决传统方式的痛点。
具体操作步骤
-
创建
compose.yaml配置文件在任意目录创建
compose.yaml,内容如下:# 项目名称(用于隔离资源,避免冲突) name: myblog # 定义服务(容器) services:# MySQL服务(对应传统的mysql容器)mysql:image: mysql:8.0 # 镜像版本ports:- "3306:3306" # 端口映射environment: # 环境变量(替代-e参数)MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: wordpressvolumes: # 卷挂载(替代-v参数)- mysql-data:/var/lib/mysql- /app/myconf:/etc/mysql/conf.drestart: always # 自动重启策略networks: # 加入的网络- blog # WordPress服务(对应传统的wordpress-app容器)wordpress:image: wordpress:latestports:- "8080:80"environment:WORDPRESS_DB_HOST: mysql # 直接通过服务名mysql访问(依赖同一网络)WORDPRESS_DB_USER: rootWORDPRESS_DB_PASSWORD: 123456WORDPRESS_DB_NAME: wordpressvolumes:- wordpress:/var/www/htmlrestart: alwaysnetworks:- blogdepends_on: # 依赖mysql服务,确保mysql先启动- mysql # 定义数据卷(替代手动创建的mysql-data和wordpress卷) volumes:mysql-data:wordpress: # 定义网络(替代docker network create blog) networks:blog:1、根节点结构必须包含 version、services,volumes 和 networks 可选(与 services 同级,无缩进)。
2、缩进规则
1)子节点相对于父节点缩进 2 个空格(不能用 Tab,YAML 不推荐)。
2)同一级别的节点(如 mysql 和 wordpress)缩进必须一致。3、短横线后必须加空格
-
一键启动所有服务
在compose.yaml所在目录执行:docker-compose -f compose.yaml up -d # -d表示后台运行
自动完成的操作(替代传统的 3 条核心命令):
1)拉取mysql:8.0和wordpress:latest镜像(本地没有时)。 、
2)创建自定义网络myblog_blog(名称格式:项目名_网络名)。
3)创建数据卷myblog_mysql-data和myblog_wordpress(自动关联挂载路径)。
4)先启动mysql容器,再启动wordpress容器(因depends_on配置)。
验证效果
docker-compose -f compose.yaml ps # 查看服务状态
docker-compose -f compose.yaml logs -f # 实时查看日志(按Ctrl+C退出)
访问博客:浏览器打开http://localhost:8080,正常显示 WordPress 初始化页面。
图示:访问workdpress初始化界面成功

4、便捷管理命令
停止服务(保留资源):docker compose stop
重启服务:docker compose restart
查看日志:docker compose logs -f(实时查看两容器日志)
彻底清理(删除容器、网络,保留卷):docker compose down
三、Docker Compose 的核心优势总结
| 对比项 | 传统方式 | Docker Compose |
|---|---|---|
| 配置管理 | 多条命令分散 | 集中于 YAML 文件 |
| 启动顺序 | 手动控制 | 自动处理依赖 |
| 维护难度 | 修改繁琐 | 修改配置即可重启 |
| 可移植性 | 环境依赖重 | 一份文件跨平台部署 |
| 清理与扩展 | 手动执行多步 | 一条命令完成 |
简言之,Docker Compose 将多容器应用的部署从 “零散命令的拼接” 转变为 “配置文件 + 标准化命令”,尤其适合 WordPress 这类依赖多个服务的应用,大幅降低了部署和维护的复杂度。
