Docker Compose 多容器编排:一条命令起整套环境
开发一个带数据库和缓存的应用时,最怕的就是"我本地能跑"。你电脑上手动敲了一堆 docker run,配好了端口、挂载了目录,换个人或者换台机器就全乱了。Docker Compose 干的事很简单:用一个 docker-compose.yml 把这套环境描述清楚,然后一句 docker compose up -d 全部拉起来。这篇文章就带你从零写一个能用的编排文件,顺便把几个容易踩的坑说清楚。
一、为什么不直接用 docker run
假设一个最小项目:一个后端服务、一个 MySQL、一个 Redis。如果手工启动,你得记三组命令,还要注意启动顺序(数据库得先起)、网络怎么互通、数据存哪儿。任意一步漏了,应用就连不上库。
| 方式 | 启动步骤 | 顺序控制 | 配置留存 | 可复现性 |
|---|---|---|---|---|
| 手工 docker run | 每条命令手动敲 | 靠人工等 | 只在终端历史里 | 差,换机器重来 |
| Docker Compose | 一份 yml + 一条命令 | depends_on 声明 | 文件化、可提交仓库 | 好,clone 即跑 |
Compose 的本质就是把"怎么起这套环境"变成一份代码,跟着项目走。
二、先搞懂三个核心概念
- service(服务):一个容器实例的声明,比如
web、mysql、redis各是一个 service。 - network(网络):Compose 默认给项目建一个桥接网络,所有 service 在同一个网段,互相能用服务名当主机名访问(
mysql:3306)。 - volume(数据卷):容器删了数据就没了,数据库这种有状态的东西必须挂卷把数据落盘。
记住一句话:service 之间靠服务名通信,有状态的数据靠 volume 持久化。
三、写一个能跑的 compose 文件
下面这份文件描述了一个常见组合:Spring Boot 后端(镜像 myapp:1.0)、MySQL 8、Redis。
version: "3.8"
services:
web:
image: myapp:1.0
build: ./backend
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/demo
SPRING_REDIS_HOST: redis
depends_on:
- mysql
- redis
networks:
- app-net
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: demo
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-net
redis:
image: redis:7
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- app-net
networks:
app-net:
driver: bridge
volumes:
mysql-data:
redis-data:
注意 web 里连数据库用的是 mysql:3306 而不是 127.0.0.1 —— 因为容器之间是通过 Compose 的网络互通的,mysql 就是服务名解析出来的主机名。

四、几个常用的配置项
- depends_on:声明启动顺序,但只保证"先启动容器",不保证"里面服务就绪"。MySQL 起来了但还没接受连接时,web 可能已经去连了。生产环境建议容器内加健康探测或重试逻辑。
- environment / env_file:注入环境变量,敏感配置别写死在 yml 里,用
env_file: .env加载。 - ports:
- "宿主机:容器",只把需要对外暴露的端口映射出来,内部服务可以不暴露。 - restart: unless-stopped:容器意外退出自动拉起,适合常驻服务。
- volumes:命名卷(
mysql-data)由 Docker 管理,比 bind mount(直接挂宿主机目录)更不容易出权限问题。
五、日常命令
docker compose up -d # 后台启动整套
docker compose ps # 看各服务状态
docker compose logs -f web # 跟踪某个服务日志
docker compose down # 停掉并删容器(卷默认保留)
docker compose down -v # 连数据卷一起删,慎用
改了 yml 之后,docker compose up -d --build 会重新构建再启动。
小结
Docker Compose 的价值在于把"环境"写成可提交、可复现的代码,解决了"我本地能跑"的尴尬。掌握好 service、network、volume 三件套,再注意 depends_on 不等就绪、数据卷权限、端口冲突这几个高频坑,基本就能应付绝大多数单机多容器场景。等规模再大、要跨机器调度时,再上 Kubernetes 也不迟。
- 点赞
- 收藏
- 关注作者
评论(0)