Docker 系列 | 08 - 多容器应用编排:Docker Compose 入门与实践
Docker 系列 | 08 - 多容器应用编排:Docker Compose 入门与实践
引言
在之前的文章中,我们学习了如何单独地运行和管理 Docker 容器。然而,在实际应用中,一个完整的服务往往由多个相互关联的容器组成,例如一个 Web 应用可能需要一个应用容器、一个数据库容器和一个缓存容器。手动管理这些容器的启动顺序、网络连接和卷挂载会非常繁琐且容易出错。
这时,Docker Compose 就派上用场了。Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过一个 YAML 文件来配置应用程序的服务,然后使用一个命令,就可以从这个配置中创建并启动所有服务。
本篇文章将带您入门 Docker Compose,学习如何编写 docker-compose.yml
文件,并实际部署一个多容器应用。
什么是 Docker Compose?
Docker Compose 是 Docker 官方提供的开源工具,它简化了多容器应用的定义和管理。其核心思想是:
- **定义 (Define)**:使用一个名为
docker-compose.yml
的 YAML 文件来定义应用程序的服务、网络和卷。 - **运行 (Run)**:通过一个简单的命令 (
docker compose up
),就可以启动、停止、重建和管理整个应用栈。
Docker Compose 的优势:
- 简化配置:将所有容器的配置集中在一个文件,清晰明了。
- 自动化部署:一个命令即可启动整个应用,无需手动逐个启动容器。
- 服务发现:Compose 默认会为您的服务创建一个自定义网络,并启用内置 DNS,允许服务之间通过名称相互通信。
- 环境一致性:Compose 文件可以在不同的开发、测试、生产环境中共享,确保环境的一致性。
安装 Docker Compose
Docker Desktop (适用于 Windows/macOS) 通常已经内置了 Docker Compose。
对于 Linux 用户,您可能需要单独安装:
**Linux 安装示例 (Compose V2 - 推荐)**:
1 | # 下载最新版本的 Compose V2 |
注意: 从 Docker Compose V2 开始,命令是 docker compose
(无连字符),而不是旧版 V1 的 docker-compose
。本文将以 V2 语法为例。
docker-compose.yml
文件结构
docker-compose.yml
是 Docker Compose 的核心配置文件,它使用 YAML 语法。以下是一个典型的 docker-compose.yml
文件的结构:
1 | version: '3.8' # Compose 文件格式版本,推荐使用最新稳定版 |
常用字段解释:
**
version
**:Compose 文件格式的版本号,如3.8
。不同版本支持的语法和功能略有不同。services
:定义应用中的各个服务。每个服务会创建一个或多个容器实例。- 服务名称:如
web
,db
。这些名称在 Compose 创建的自定义网络中可作为 hostname 进行服务发现。 - **
build
**:指定 Dockerfile 所在目录(或包含Dockerfile
的构建上下文)。如果指定了,Compose 会先构建镜像。 - **
image
**:指定要使用的 Docker 镜像名称。如果build
和image
都指定,build
会优先。 - **
ports
**:端口映射,格式为宿主机端口:容器端口
。 - **
volumes
**:卷挂载,格式为宿主机路径:容器路径
(绑定挂载) 或命名卷名称:容器路径
(命名卷)。 - **
environment
**:定义环境变量,会传递到容器内部。 depends_on
:声明服务之间的依赖关系。例如web
依赖db
,则db
会先于web
启动。注意:depends_on
仅保证启动顺序,不保证服务就绪(如数据库连接已建立)。对于就绪检查,应使用healthcheck
。- **
networks
**:指定服务连接到哪个网络。如果未指定,Compose 会创建一个默认的桥接网络并将所有服务连接到它。 - **
healthcheck
**:定义容器的健康检查。当健康检查通过后,Compose 才会认为服务是“就绪”的。
- 服务名称:如
**
volumes
**:顶级字段,用于定义命名卷。这些卷可以被多个服务共享。**
networks
**:顶级字段,用于定义自定义网络。这些网络可以被多个服务共享,实现服务发现。
Docker Compose 常用命令
在包含 docker-compose.yml
文件的目录中执行以下命令:
docker compose up
:构建(如果需要)并启动
docker-compose.yml
中定义的所有服务。-d
:在后台运行容器(detached mode)。
--build
:强制重建镜像(即使没有 Dockerfile 变化)。docker compose down
:- 停止并删除所有服务容器、网络和默认卷。
-v
:同时删除命名卷(慎用,会删除数据)。
docker compose ps
:- 列出所有服务的容器状态。
docker compose logs [service_name]
:- 查看服务的日志输出。
-f
:实时跟踪日志。
**
docker compose exec <service_name> <command>
**:- 在指定服务的运行中容器内执行命令。
docker compose exec web bash
:进入web
服务的容器终端。**
docker compose build [service_name]
**:- 构建或重建指定服务的镜像。
**
docker compose pull [service_name]
**:- 拉取指定服务所需的镜像。
**
docker compose top
**:- 查看服务的进程。
Docker Compose 实践:一个简单的 Flask 应用 + PostgreSQL 数据库
我们将使用 Docker Compose 来部署一个典型的 Web 应用(Flask)和数据库(PostgreSQL)组合。
项目结构:
1 | my-flask-app/ |
app/app.py
(Flask 应用代码 - 假设会连接到 PostgreSQL):
1 | from flask import Flask |
app/requirements.txt
:
1 | Flask==2.0.3 |
Dockerfile
(在 app/
目录下创建,如果需要构建 Flask 镜像):
1 | FROM python:3.9-slim-buster |
注意:在 docker-compose.yml
中,我们可以选择 build: ./app
来让 Compose 根据这个 Dockerfile 构建镜像,也可以直接使用预构建的镜像 image: my-flask-app:1.0
。这里我们选择 build
。
docker-compose.yml
:
1 | version: '3.8' |
部署步骤:
将上述文件保存到
my-flask-app
目录及其子目录app/
中。打开终端,进入
my-flask-app
目录。启动应用栈:
1
docker compose up -d
这个命令会自动构建 web
服务的镜像,拉取 postgres
镜像,创建 db_data
命名卷和 app_network
网络,然后启动 db
服务,接着启动 web
服务,并将它们连接到 app_network
。
检查服务状态:
Bash
1
docker compose ps
您应该看到
web
和db
服务都在运行。查看日志 (可选):
Bash
1
2docker compose logs web
docker compose logs db访问应用: 在浏览器中访问
http://localhost:5000
。如果一切顺利,您应该看到 “Hello from Flask! Connected to PostgreSQL successfully!” 的消息。停止并清理:
1
docker compose down
这会停止并删除
web
和db
容器,以及app_network
网络。但db_data
命名卷默认不会被删除(除非您使用-v
选项)。
结语
通过本篇文章,我们详细了解了 Docker Compose 的概念、其 YAML 文件的结构以及常用的命令。通过一个 Flask 应用与 PostgreSQL 数据库的实例,您已经掌握了如何使用 Docker Compose 来定义和部署一个多容器应用。
Docker Compose 极大地简化了本地开发和测试环境的搭建,是 Docker 生态系统中不可或缺的工具。在下一篇文章中,我们将学习如何将本地构建的 Docker 镜像推送到远程仓库,特别是 Docker Hub,实现镜像的共享和分发。