docker-compose down
到底发生了什么?
想象一下你有一座由多个房间组成的房子(多个容器),每个房间都有自己独立的功能(服务)。当你决定要“关闭”这座房子时,你需要:
- 通知所有人离开:确保所有正在运行的服务安全停止。
- 清理房间:移除所有临时创建的资源,比如临时文件或网络连接。
- 锁好门窗:确保没有任何东西被遗留在外面,比如挂载的数据卷。
- 拆除临时搭建的结构:如果有必要,可以删除为这些房间创建的专用网络。
docker-compose down
就是这样一个“关闭”命令,它会做以下几件事情:
- 停止并移除容器:停止所有正在运行的容器,并将它们从系统中移除。
- 移除网络:移除为这些容器创建的专用 Docker 网络。
- 可选地移除卷和镜像:根据提供的选项,还可以移除与这些容器关联的数据卷和镜像。
底层原理
docker-compose down
的工作流程依赖于以下几个关键步骤和技术:
- 解析配置文件:读取并解析
docker-compose.yml
文件,了解哪些服务需要停止和移除。 - 停止容器:向每个容器发送一个信号(通常是 SIGTERM),告诉它们准备停止。然后等待一段时间让容器优雅地关闭。如果容器没有在规定时间内停止,可能会发送 SIGKILL 强制终止。
- 移除容器:使用 Docker API 或 CLI 命令移除容器,释放它们占用的资源。
- 移除网络:移除为这些容器创建的专用 Docker 网络,以清理网络配置。
- 移除卷(可选):如果有
-v
或--volumes
选项,Docker Compose 会移除与这些容器关联的数据卷。 - 移除镜像(可选):如果有
--rmi
选项,Docker Compose 会尝试移除不再使用的镜像。
使用场景
docker-compose down
非常适合以下几种场景:
- 开发结束:当开发或测试完成后,可以使用
docker-compose down
来清理环境。 - 重新部署:在更新应用程序之前,先使用
docker-compose down
移除旧版本的容器和服务。 - 节省资源:如果你不需要某些服务运行,可以通过
docker-compose down
释放系统资源。
PHP 实例代码和详细注释
假设我们有一个简单的 PHP Web 应用程序和 MySQL 数据库的组合,我们已经用 docker-compose up -d
启动了它们。现在我们要停止并清理这些服务。
目录结构
my_php_app/
├── docker-compose.yml
├── php/
│ └── Dockerfile
└── web/
└── index.php
index.php
内容(简化版)
<?php
// 连接MySQL数据库并查询一条记录
$host = 'db'; // 注意这里使用的是容器名称作为主机名
$username = 'user';
$password = 'password';
$database = 'mydb';
try {
$pdo = new PDO("mysql:host=$host;dbname=$database", $username, $password);
$stmt = $pdo->query("SELECT 'Hello from MySQL!' AS message");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['message'];
} catch (PDOException $e) {
die("Could not connect to the database: " . $e->getMessage());
}
?>
php/Dockerfile
内容
# 使用官方 PHP 镜像作为基础镜像,包含 PHP-FPM 和 MySQL 扩展
FROM php:7.4-fpm
# 安装 MySQL 扩展
RUN docker-php-ext-install pdo pdo_mysql
# 设置工作目录
WORKDIR /var/www/html
# 将当前目录下的所有文件复制到容器中的 /var/www/html 目录
COPY ../web ./
# 暴露容器的9000端口,用于PHP-FPM通信
EXPOSE 9000
docker-compose.yml
内容
version: '3'
services:
web:
build: ./php
volumes:
- ./web:/var/www/html
ports:
- "8080:80"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
清理应用
在项目根目录下执行以下命令来停止并清理所有服务:
# 停止并移除容器、网络,但保留数据卷
docker-compose down
# 如果你还想移除数据卷,可以加上 -v 参数
# docker-compose down -v
详细注释
-
index.php
文件:- 尝试连接到名为
db
的 MySQL 数据库容器,并查询一条问候信息。 - 如果连接成功,则输出从数据库获取的消息;如果失败,则显示错误信息。
- 尝试连接到名为
-
php/Dockerfile
文件:FROM php:7.4-fpm
:指定基础镜像为带有 PHP-FPM 的 PHP 7.4 版本。RUN docker-php-ext-install pdo pdo_mysql
:安装 MySQL 数据库扩展,以便 PHP 可以与 MySQL 通信。WORKDIR /var/www/html
:设置容器内部的工作目录为/var/www/html
。COPY ../web .
:将当前目录下的web
文件夹中的所有文件复制到容器的/var/www/html
目录。EXPOSE 9000
:声明容器内的 PHP-FPM 服务监听端口9000。
-
docker-compose.yml
文件:version: '3'
:指定 Docker Compose 文件版本。services
:定义了两个服务web
和db
。web
服务:build: ./php
:基于php/Dockerfile
构建镜像。volumes
:将本地web
目录挂载到容器内的/var/www/html
目录,以便实时更新代码。ports
:将主机的8080端口映射到容器的80端口。depends_on
:确保web
服务启动前db
服务已经启动。
db
服务:image: mysql:5.7
:使用官方 MySQL 5.7 镜像。environment
:设置 MySQL 数据库的环境变量。volumes
:将数据持久化存储到名为db_data
的卷中。
volumes
:定义了一个名为db_data
的卷,用于持久化 MySQL 数据。
总结
docker-compose down
是一个非常有用的命令,它可以帮助我们安全地停止并清理 Docker Compose 管理的所有容器和服务。其底层原理包括解析配置文件、停止容器、移除容器、移除网络以及根据选项移除卷和镜像。通过上面的例子,我们可以看到如何创建一个简单的 PHP Web 应用程序,并使用 docker-compose down
命令来停止和清理这些服务。