第二部分:从 Docker 到 Docker Compose

📝 前言

欢迎来到《云原生之旅第二部分》的第五篇文章。

在前四篇中,我们已经一起探索了 Docker 的基础知识、进阶功能和在 AI 领域的应用:

现在,我们将从 Docker 扩展到 Docker Compose 领域。

🧭 背景介绍

在我从 Android 专向 Web 开发后,有个困扰我的问题就是后端服务比较多,而且它们之间还有复杂的依赖关系。

手动管理这些服务不仅麻烦,还容易出错,这时候 Docker 能帮你把每个服务打包成容器,但如何高效管理多个容器,并确保它们按正确的顺序启动和通信呢?

直到我接触到了 Docker Compose,它就是解决这个问题的利器!

它让你用一份配置文件定义所有服务,自动处理依赖关系,真正实现一键启动整个环境。

🧠 本章知识卡片

🔍 使用场景

Docker Compose 主要适用于以下场景:

  • 本地开发环境搭建

快速启动一个包含前后端+数据库的完整开发环境。

  • 微服务架构调试

同时运行多个相互依赖的微服务(如API网关、用户服务、订单服务)。

  • 生产环境轻量级部署

小型项目或边缘计算场景下,用 Compose 替代 Kubernetes。

📋 前提条件

在正式进入实战之前,请确保你已经具备以下条件:

🚀 本章小节

1️⃣ 什么是 Docker Compose?

Docker Compose 是一个用于定义和运行多容器应用的工具,特别适合管理由多个服务组成的应用栈。

Compose 简化了整个应用堆栈的控制,使得管理服务、网络和卷变得轻而易举。

你可以在一个 YAML 配置文件中轻松管理这些内容。然后,只需一条命令,你就可以从配置文件中创建并启动所有服务。

PS:另外自 2023 年 7 月起,Docker Compose V1 版本已停止维护,请尽量直接使用 V2 版本。

安装最新版本 Docker Desktop 就已经包含了 Docker Compose V2,可通过以下命令进行测试验证:

1
2
# V2 与 V1 版本区别很大,V1 版本命令是 docker-compose
docker compose version

2️⃣ Docker Compose 常用命令

以下是一些 Compose 的常用命令操作:

命令 功能说明
docker compose up -d 在后台启动所有服务
docker compose down 停止并移除所有容器和网络
docker compose build 构建服务使用的镜像
docker compose ps 查看服务容器状态
docker compose logs 查看所有服务日志
docker compose logs <服务名> 查看指定服务日志
docker compose exec <服务名> bash 进入容器内部操作

3️⃣ Docker Compose 基础概念与配置

一个典型的 docker-compose.yml 文件包括以下核心配置:

3.1 Services 介绍

services 是 Compose 的核心,每个服务都表示一个容器。例如:

1
2
3
4
5
services:
web:
image: nginx:alpine
db:
image: mysql:8.0

每个服务可以配置自己的网络、卷、端口、环境变量等。

3.2 Ports 介绍

ports 用于将容器内部端口映射到主机,同docker命令的-p参数,配置参考如下:

1
2
ports:
- "8080:80" # 本机8080 -> 容器80

多个服务可暴露不同端口供外部访问。

3.3 Environment 介绍

environment 用于配置容器内的环境变量,同docker命令的-e参数:

1
2
3
environment:
- MYSQL_ROOT_PASSWORD=secret
- TZ=Asia/Shanghai

也可以通过 .env 文件统一管理(见后续章节)。

3.4 Volumes 介绍

volumes 用于挂载持久化数据或配置文件,同docker命令的-v参数,配置参考如下:

1
2
volumes:
- ./data:/var/lib/mysql

它可以持久保存数据库数据或映射配置文件,避免容器重启丢失数据。

3.5 Networks 介绍

Compose 默认会创建一个网络,服务之间可以通过名称互相通信。

也可以自定义多个网络:

1
2
3
networks:
backend:
frontend:

然后在服务中指定:

1
2
3
4
services:
web:
networks:
- frontend

4️⃣ Docker Compose 实战演示

下面通过一个实战的示例加深理解。

4.1 批量构建多个镜像

当你有多个服务使用build字段可分别指定 Dockerfile,配置参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
services:
backend:
build: ./backend
ports:
- "8000:8000"
frontend:
build: ./frontend
ports:
- "3000:80"
environment:
- NEXT_PUBLIC_API_URL=http://localhost:8000
# 表示依赖后端服务
depends_on:
- backend

使用以下命令,即可一次性构建所有服务镜像:

1
docker compose build

完整项目示例代码:https://github.com/lusyoe/python-docker-compose-demo

4.2 批量启动多个容器

使用如下命令一键启动所有服务:

1
docker compose up -d --build

参数说明:

  • -d:表示后台运行。
  • --build:表示同时进行镜像构建。

启动后可通过浏览器访问:http://localhost:3000查看页面打印信息,如下图:

4.3 查看服务状态

查看当前 Compose 项目的所有服务运行状态:

1
docker compose ps

4.4 查看指定服务日志

查看 backend 服务的日志:

1
docker compose logs backend

也可添加 -f 参数持续输出(类似 tail):

1
docker compose logs -f backend

5️⃣ Docker Compose 最佳实践

5.1 使用.env文件管理环境变量

当容器所需的环境变量较多时,如果都使用environment,将会显示的很长很长,可通过引用文件的形式批量注入,在docker-compose.yaml文件同级目录下创建.env文件,内容如下:

1
NEXT_PUBLIC_API_URL=http://localhost:8000

修改docker-compose文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
services:
backend:
build: ./backend
ports:
- "8000:8000"
frontend:
build:
context: ./frontend
# 仅在构建时引用
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
ports:
- "3000:80"
depends_on:
- backend

如果需要在容器运行时引用,可使用env_file:

1
2
3
4
5
6
7
services:
backend:
build: ./backend
env_file:
- .app.env # 加载这个文件中的变量到容器环境
ports:
- "8000:8000"

5.2 多环境部署(dev / prod)

可通过不同配置文件实现环境隔离:

1
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

docker-compose.prod.yml 中可覆盖默认配置,如开启日志挂载、关闭调试模式等。

5.3 引用其他compose文件(include)

将公共配置拆分为多个文件,可通过include引用,示例如下:

1
2
3
4
5
6
7
include:
- backend-include.yaml
services:
frontend:
build: .
depends_on:
- backend

5.4 启用 GPU 访问

在支持 NVIDIA GPU 的机器上,需要提前安装好驱动NVIDIA Container Toolkit(可参看上一篇文章:《第二部分:Docker GPU 容器实战指南》),然后使用如下配置启用 GPU:

1
2
3
4
5
6
7
8
9
10
11
12
services:
test:
image: nvidia/cuda:12.9.0-base-ubuntu22.04
command: nvidia-smi
deploy:
resources:
reservations:
devices:
- driver: nvidia
# 限制分配给服务容器的 GPU 设备数量
count: 1
capabilities: [gpu]

✅ 总结

在容器化时代,Docker Compose 是从单一容器开发过渡到多服务协同的关键工具。

它以配置即代码的方式,将服务定义、环境变量、端口映射、数据卷挂载等内容统一在一个或多个 YAML 文件中,使得开发、测试、部署过程更加一致、可复用、易维护

但 Docker Compose 也有其局限性,即只能针对单机进行部署,若是针对大规模的容器应用管理,还是需要 Kubernetes,这在后续的章节中会更详细的进行介绍,感兴趣的同学可以持续关注~

📎 参考文章