如何使用 docker stack config 命令检查合并后的 Compose 文件

DockerBeginner
立即练习

介绍

在本次实验中,你将学习如何使用 docker stack config 命令来检查 Docker Compose 文件最终合并后的配置。这对于理解 Docker 如何解释你的 Compose 定义至关重要,尤其是在处理多个文件或环境变量时。你将从输出单个 Compose 文件的配置开始,包括在 LabEx 环境中安装 Docker Compose 的必要步骤。

接下来,你将探索如何合并并输出多个 Compose 文件的配置,展示 Docker 如何组合来自不同源的定义。你还将学习如何直接从标准输入输出配置,以及在生成配置输出时如何跳过环境变量的插值。这些步骤将让你全面了解 docker stack config 命令在调试和验证 Docker Compose 设置方面的功能。

从单个 Compose 文件输出最终配置

在这一步中,你将学习如何从单个 Docker Compose 文件输出最终配置。这对于调试或了解在处理完所有变量和扩展后 Compose 文件的最终状态很有用。

首先,让我们安装 Docker Compose。由于它没有预先安装在 LabEx 虚拟机环境中,我们需要下载并安装它。我们将下载最新的稳定版本。

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

此命令从官方 GitHub 仓库下载 Docker Compose 二进制文件。$(uname -s)$(uname -m) 用于获取虚拟机的操作系统和架构,确保你下载的是正确的二进制文件。

接下来,我们需要为下载的二进制文件赋予可执行权限。

sudo chmod +x /usr/local/bin/docker-compose

此命令使 docker-compose 命令可执行。

现在,让我们通过检查版本来验证安装情况。

docker-compose --version

你应该会在控制台看到已安装的 Docker Compose 版本。

在输出配置之前,我们需要一个 Docker Compose 文件。让我们在 ~/project 目录中创建一个简单的文件。

nano ~/project/docker-compose.yaml

将以下内容粘贴到 docker-compose.yaml 文件中:

version: "3.8"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

这是一个简单的 Compose 文件,它定义了一个名为 web 的服务,使用 nginx:latest 镜像,并将主机上的 80 端口映射到容器内的 80 端口。

Ctrl + X,然后按 Y,再按 Enter 保存文件。

现在,导航到保存 docker-compose.yaml 文件的 ~/project 目录。

cd ~/project

要从这个 Compose 文件输出最终配置,我们使用 docker-compose config 命令。

docker-compose config

此命令读取当前目录中的 docker-compose.yaml 文件,并将最终合并的配置输出到标准输出。你应该会看到 docker-compose.yaml 文件的 YAML 内容被打印出来,可能还会有 Docker Compose 添加的一些额外默认值。

合并并输出多个 Compose 文件的配置

在这一步中,你将学习如何合并多个 Docker Compose 文件的配置,并输出最终合并后的配置。这是一个强大的功能,允许你定义一个基础配置,然后使用额外的文件对其进行覆盖或扩展,这对于管理不同的环境(例如开发、预发布、生产环境)非常有用。

我们将继续在 ~/project 目录中进行操作。在上一步中,我们创建了一个 docker-compose.yaml 文件。现在,让我们创建另一个 Compose 文件来扩展基础配置。我们将其命名为 docker-compose.override.yaml

nano ~/project/docker-compose.override.yaml

将以下内容粘贴到 docker-compose.override.yaml 文件中:

version: "3.8"
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html

这个覆盖文件修改了 docker-compose.yaml 中定义的 web 服务。它将主机端口映射从 80 改为 8080,并添加了一个卷挂载,用于从名为 html 的本地目录提供静态 HTML 内容。

Ctrl + X,然后按 Y,再按 Enter 保存文件。

现在,让我们创建 html 目录,并在其中创建一个简单的 index.html 文件。

mkdir ~/project/html
nano ~/project/html/index.html

将以下内容粘贴到 ~/project/html/index.html 中:

<h1>Hello from Nginx!</h1>

Ctrl + X,然后按 Y,再按 Enter 保存文件。

默认情况下,Docker Compose 会自动在当前目录中查找 docker-compose.yamldocker-compose.override.yaml 并将它们合并。覆盖文件中的配置优先级更高。

要查看合并后的配置,请确保你位于 ~/project 目录中,然后再次运行 docker-compose config 命令。

cd ~/project
docker-compose config

现在你应该会看到合并后的配置,其中 web 服务的端口映射为 8080:80,并且有卷挂载 ./html:/usr/share/nginx/html

你还可以使用 -f 标志显式指定要使用的 Compose 文件。指定文件的顺序很重要,因为后面的文件会覆盖前面的文件。

例如,要显式合并 docker-compose.yamldocker-compose.override.yaml,你可以运行:

docker-compose -f docker-compose.yaml -f docker-compose.override.yaml config

在这种情况下,这将产生与不使用 -f 标志运行 docker-compose config 相同的合并输出,因为 docker-compose.override.yaml 会在 docker-compose.yaml 之后被自动检测并合并。

从标准输入输出配置

在这一步中,你将学习如何从通过标准输入(stdin)提供的 Docker Compose 文件输出最终配置。当你想动态生成 Compose 文件,或者将另一个命令的输出直接通过管道传递给 docker-compose config 时,这种方法很有用。

我们将继续在 ~/project 目录中操作。我们不会从文件中读取内容,而是将 Compose 配置的内容直接通过管道传递给 docker-compose config 命令。

让我们使用 cat 命令输出 docker-compose.yaml 文件的内容,并将其通过管道传递给 docker-compose config

cd ~/project
cat docker-compose.yaml | docker-compose config -f -

在这个命令中:

  • cat docker-compose.yamldocker-compose.yaml 文件的内容输出到标准输出。
  • | 是管道操作符,它将 cat 命令的标准输出重定向到 docker-compose config 命令的标准输入。
  • docker-compose config -f - 告诉 docker-compose config 从标准输入(-)而不是文件中读取配置。

你应该会看到与第一步中运行 docker-compose config 时相同的输出,即 docker-compose.yaml 中的配置。

你也可以直接通过管道传递不同的配置。例如,让我们通过管道传递一个 redis 服务的简单配置。

echo "version: '3.8'\nservices:\n  redis:\n    image: redis:latest" | docker-compose config -f -

在这个命令中:

  • echo "version: '3.8'\nservices:\n redis:\n image: redis:latest" 输出一个包含 redis 服务的简单 Compose 文件的 YAML 字符串。\n 在输出中创建换行符。
  • | 将这个字符串通过管道传递给 docker-compose config 命令。
  • docker-compose config -f - 从标准输入读取配置。

输出应该是 redis 服务的 YAML 配置。

当你以编程方式生成 Compose 配置,或者想快速测试一个配置而不将其保存到文件时,这种方法特别有用。

跳过变量插值输出合并后的配置

在这一步中,你将学习如何从多个 Docker Compose 文件输出合并后的配置,同时跳过变量插值。默认情况下,docker-compose config 会对环境变量进行插值处理。当你想查看仍包含变量的原始配置时,跳过插值会很有用,例如在调试或生成模板时。

我们将继续在 ~/project 目录中使用 docker-compose.yamldocker-compose.override.yaml 文件进行操作。

首先,让我们在 docker-compose.yaml 文件中添加一个环境变量,以演示插值处理。

nano ~/project/docker-compose.yaml

修改 docker-compose.yaml 文件,在镜像名称中包含一个环境变量:

version: "3.8"
services:
  web:
    image: nginx:${NGINX_VERSION:-latest}
    ports:
      - "80:80"

在这里,${NGINX_VERSION:-latest} 是一个变量,它将被 NGINX_VERSION 环境变量的值替换。如果未设置 NGINX_VERSION,则默认为 latest

Ctrl + X,然后按 Y,再按 Enter 保存文件。

现在,让我们设置 NGINX_VERSION 环境变量,然后运行 docker-compose config 来查看插值处理的效果。

cd ~/project
export NGINX_VERSION=1.21
docker-compose config

你应该会看到合并后的配置,并且 web 服务的镜像名称现在应该是 nginx:1.21

要输出合并后的配置而不进行变量插值,我们在 docker-compose config 命令中使用 --no-interpolate 标志。

docker-compose --no-interpolate config

这一次,输出应该显示镜像名称为 nginx:${NGINX_VERSION:-latest},变量占位符仍然存在,即使已经设置了 NGINX_VERSION 环境变量。

当你想查看 Compose 文件中原始编写的精确配置,而不进行任何变量替换时,这个标志很有帮助。

总结

在本次实验中,你学习了如何使用 docker-compose config 命令来检查 Docker Compose 文件的最终配置。你首先在 LabEx 虚拟机环境中安装了 Docker Compose,确保为系统架构下载了正确的二进制文件并赋予其可执行权限。然后,你通过检查版本来验证安装是否成功。

安装完成后,你创建了一个简单的 docker-compose.yaml 文件,用于定义一个基本的 Web 服务。接着,你使用 docker-compose config 命令从这个单一的 Compose 文件输出最终配置,展示了如何查看 Compose 定义的处理状态。