Docker Compose 入门:用一个 YAML 文件编排多容器应用
学会了 docker run 之后,很多初学者会遇到一个现实问题:真实的应用很少是单个容器。一个常见的 Web 应用可能需要 Nginx 做反向代理、应用服务处理业务逻辑、MySQL 存储数据。如果每个容器都要手写一长串 docker run 命令来启动,不仅繁琐,而且容器之间的依赖顺序、网络互通、数据卷挂载都很容易出错。Docker Compose 就是为了解决这个问题而生的工具:用一个 YAML 文件描述整个应用的所有服务,然后一条命令完成启动、停止和日常运维。
一、Docker Compose 是什么
Docker Compose 是 Docker 官方提供的多容器编排工具。它的核心思想是"声明式":你不需要关心容器按什么顺序启动,只需要在 docker-compose.yml 文件中声明"我需要哪些服务、每个服务用什么镜像、暴露哪些端口、挂载哪些数据卷",Compose 会负责把它们组织起来,创建好容器、网络和数据卷。
Compose 启动的所有容器默认会被放到同一个自定义网络中,容器之间可以直接用"服务名"作为主机名互相访问。例如应用容器连接 mysql:3306 就能访问到 MySQL 服务,不需要记忆 IP 地址,服务重启后 IP 变化也不受影响。
二、安装与版本验证
如果你安装的是较新版本的 Docker(20.10 及以上),Compose 已经作为插件内置,无需单独安装。可以通过下面命令验证:
docker compose version
如果输出类似 Docker Compose version v2.x.x,说明已经可用。注意新版命令是 docker compose(空格),旧版独立二进制是 docker-compose(连字符),本文统一使用新版语法。
三、认识 docker-compose.yml 文件结构
docker-compose.yml 是 Compose 的核心,一个典型的最小文件长这样:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
逐行解读:
services:定义应用包含的所有服务,每个服务最终对应一个或多个容器。web:服务名,可以自定义,同一网络内的其他容器可以用这个名字访问它。image:服务使用的镜像,这里使用轻量的nginx:alpine。ports:端口映射,格式为"宿主机端口:容器端口",访问宿主机 8080 端口就会转发到容器的 80 端口。
YAML 对缩进非常敏感,必须使用空格缩进,不能使用 Tab,这是新手最常踩的坑,报错时先检查缩进。
四、第一个实战:用 Compose 启动一个静态站点
创建一个工作目录,准备一个简单的页面和 Compose 文件:
mkdir compose-demo && cd compose-demo
新建 index.html:
<!DOCTYPE html>
<html><body><h1>Hello, Docker Compose!</h1></body></html>
新建 docker-compose.yml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./index.html:/usr/share/nginx/html/index.html:ro
这里新增了 volumes 配置,把宿主机的 index.html 挂载到 Nginx 的默认站点目录,ro 表示只读挂载。启动服务:
docker compose up -d
-d 表示后台运行。浏览器访问 http://服务器IP:8080,就能看到页面。查看运行状态和日志:
docker compose ps
docker compose logs web
停止并清理:
docker compose down
五、常用命令速查
| 命令 | 作用 |
|---|---|
docker compose up -d |
后台启动所有服务 |
docker compose down |
停止并删除容器、网络 |
docker compose ps |
查看服务运行状态 |
docker compose logs -f 服务名 |
跟踪查看服务日志 |
docker compose exec 服务名 sh |
进入运行中的容器 |
docker compose restart 服务名 |
重启指定服务 |
docker compose config |
校验 YAML 并输出解析后的完整配置 |
注意:down 默认不会删除数据卷,加上 -v 参数才会删除命名卷,清理生产数据时要格外小心。
六、进阶实战:WordPress + MySQL 双服务编排
下面用一个更贴近真实场景的例子:博客系统 WordPress 依赖 MySQL 数据库,两个容器必须协同工作:
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: example_root_pw
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: example_pw
volumes:
- db_data:/var/lib/mysql
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: example_pw
WORDPRESS_DB_NAME: wordpress
depends_on:
- db
volumes:
db_data:
几个新知识点:
environment:向容器传入环境变量,MySQL 和 WordPress 镜像都通过环境变量完成初始化配置。depends_on:声明依赖关系,Compose 会先启动db再启动wordpress。注意它只保证启动顺序,不保证数据库已经就绪,应用层最好有连接重试机制。volumes(顶层):声明命名卷db_data,数据库文件持久化保存,即使容器删除重建数据也不会丢失。- 服务间通信:
WORDPRESS_DB_HOST: db:3306中的db就是服务名,Compose 内置的 DNS 会把它解析到数据库容器的地址。
执行 docker compose up -d,稍等片刻后访问 http://服务器IP:8080,按向导完成 WordPress 安装即可。
七、写好 Compose 文件的几个建议
- 一个文件只描述一个应用:不要把不相关的服务塞进同一个文件,不利于维护和排障。
- 敏感信息不要写死:数据库密码等建议通过
.env文件或环境变量传入,在docker-compose.yml中用${MYSQL_PASSWORD}的形式引用。 - 固定镜像版本:用
mysql:8.0而不是mysql:latest,避免某天拉到大版本升级导致不兼容。 - 数据一定要用命名卷:数据库、上传文件等需要持久化的数据必须挂载命名卷,防止误删。
- 先
config再up:docker compose config可以校验 YAML 语法并输出解析后的完整配置,排查缩进错误很好用。
八、总结
Docker Compose 把"一堆容器"变成"一个应用"来管理:docker-compose.yml 描述期望状态,up/down/ps/logs 等命令完成日常运维。掌握本文的单服务启动、端口与数据卷映射、环境变量、多服务依赖和命名卷这几个核心用法,就足以应付开发、测试环境的大部分多容器场景。下一步可以继续学习扩缩容(--scale)、健康检查(healthcheck)以及 Compose 与 Kubernetes 的关系,逐步过渡到生产级编排。
- 点赞
- 收藏
- 关注作者
评论(0)