
HereDoc 符号在 Bash、SQL、PHP 和其他脚本语言中已经使用了很长时间。它允许将一个非常长的命令分解成几个更易读的行,同时仍被视为一个单一命令。
例如,在 PHP 中,与其使用像这样的 SQL 命令:
$sql = SELECT * FROM MyTable WHERE col1 < 100 and col2 > 200 ORDER BY name
相反,你可以通过将命令的组件分解到文件中的多行来使其更具可读性,同时仍然将该命令作为单个命令执行,就像这样:
$sql = <<<SQL
SELECT * FROM MyTable
WHERE col1 < 100 and col2 > 200
ORDER BY name
SQL;
当然,这涉及到更多的字符,但许多人发现这种格式更容易阅读和理解。
2021 年,Docker 的 Buildkit 开始在 Dockerfile 中使用 HereDoc 符号。这使得 Dockerfile 可以包含看起来像多个命令的条目。但实际上,它们被分解为一个单一命令,而且重要的是,在生成的镜像中只成为一层,而不是 Dockerfile 中每行一层。
所以,与其使用像这样的 Dockerfile:
FROM docker.io/redhat/ubi9-minimal as builder
RUN microdnf update
RUN microdnf -y install gcc
RUN microdnf -y install glibc-static
RUN microdnf -y install procps-ng
你可以改为使用像这样的 Dockerfile:
FROM docker.io/redhat/ubi9-minimal as builder
RUN <<EOF
microdnf update
microdnf -y install gcc
microdnf -y install glibc-static
microdnf -y install procps-ng
EOF
现在,这四个 microdnf 命令作为一行运行,在镜像中创建了一个单一层,而不是像第一个 Dockerfile 中那样,每个 RUN 命令都创建一层。虽然这个特定示例的可读性没有显著提高,但在许多情况下,Containerfile 可以通过使用 HereDoc 语法来提高可读性。
Buldah 团队收到了几项请求,要求将此功能整合到 Buildah 和 Podman 使用的 Containerfile 语法中。2023 年秋季,Aditya Rajan 创建了这个 拉取请求,以响应这个 问题,最初将该功能整合到 Buildah 中,用于 Containerfile 中的 `RUN`、`COPY` 和 `ADD` 命令。这已在 Buildah v1.33 和 Podman v4.9 中落地。然而,HereDoc 代码进行了进一步的更改,这些更改已在 Buildah v1.35 和 Podman v5.0 中落地,使其功能完善。
现在,随着 Podman 和 Buildah 的最新版本发布,Containerfile 中的 HereDoc 语法已得到全面完善。尽管它已经推出几个月了,但我认为 Podman 和 Buildah 的 Containerfile 中 HereDoc 语法的知名度并不高。我希望这篇文章能让你了解 Podman 和 Buildah 现在可以使用的这个新语法选项,并且你可以利用它使你的环境中 Containerfile 更具可读性,同时可能减少生成的容器镜像中的层数。
发表评论