跳到内容

元数据卡

  • 前置知识:Dockerfile 基础(上一页)
  • 预计时间:10 分钟
  • 完成标志:能用 docker-compose.yml 定义并启动多服务应用

你的进度

单个容器太简单了。你的真实项目不是单打独斗——它可能需要数据库、缓存服务,多个程序要相互通信。

"手动给每间房子造个网太烦了,"你说,"每次都得敲同样的端口映射命令。有没有一种办法,一次性定义好哪些服务要启动、它们之间怎么连?"


用 Compose 定义多服务

Docker Compose 是一个用 YAML 文件一次性定义多间房子的方案。

创建一个 docker-compose.yml

yaml
version: '3.8'

services:
 db:
 image: mysql:8.0
 environment:
 MYSQL_ROOT_PASSWORD: rootpass
 MYSQL_DATABASE: mydb
 ports:
 - "3306:3306"
 volumes:
 - db-data:/var/lib/mysql

 app:
 build: .
 ports:
 - "8080:8080"
 environment:
 SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb
 depends_on:
 - db

volumes:
 db-data:

然后一行命令起飞:

bash
docker compose up -d

查看所有容器的日志:

bash
docker compose logs -f

收摊:

bash
docker compose down

注意到 depends_on 了吗?它确保 MySQL 先启动,应用后启动。但注意——depends_on 只保证启动顺序,不保证 MySQL 已经可以接受连接。你的应用代码里还需要加重试逻辑。

Volume 持久化数据

容器默认的文件系统是活着的,但死了就没了。当你 docker rmdocker run——数据全没了。

要持久化数据,必须用 Volume(卷)

bash
# 创建卷
docker volume create my-db-data

# 挂载卷到容器
docker run -v my-db-data:/var/lib/mysql mysql:8.0

即使容器被删除了,卷里还留着数据。你能找到卷的真实路径:

bash
docker volume inspect my-db-data

docker-compose.yml 里,volumes: db-data: 定义了一个卷,然后在 db 服务里用 - db-data:/var/lib/mysql 挂载它。


常见陷阱

容器里的时间怎么是 UTC?

bash
# 解决:挂载宿主机的时区文件
docker run -v /etc/localtime:/etc/localtime:ro my-image

容器日志太多撑爆磁盘了?

bash
docker run --log-opt max-size=10m --log-opt max-file=3 my-image

在 Compose 里:

yaml
services:
 app:
 logging:
 driver: json-file
 options:
 max-size: "10m"
 max-file: "3"

旅人笔记

Docker Compose 让你用一份 YAML 文件定义应用的所有服务。数据库、缓存、应用本身——一条命令启动,一条命令收摊。depends_on 控制启动顺序,Volume 保证容器挂了数据不丢。

下一步:Docker 练习

动手实操才能真正掌握。来练练手。

Docker 练习 →

Built with VitePress | Software Systems Atlas