heredoc 是什么
较新的 Dockerfile 前端支持在指令里内嵌多行文本:RUN 后面跟一段以分隔符包裹的脚本,或 COPY 后面直接写文件内容。这样写多行脚本不再需要大量反斜杠续行,可读性明显提高,也减少了转义错误。它属于前端提供的新语法,文件首行需要声明对应的前端版本。
基本信息
| 前置条件 | 首行写 # syntax=docker/dockerfile:1(前端 1.4 及以上) |
|---|---|
| RUN 形式 | RUN <<EOF 换行脚本内容 换行 EOF |
| COPY 形式 | COPY <<EOF /目标路径 换行文件内容 换行 EOF |
| 变量展开 | 分隔符加引号(如 <<'EOF')可关闭变量与命令替换 |
| 结束标记 | 必须单独成行且顶格,无法识别时会报未结束 |
| 多段使用 | 同一指令可连续使用多个 heredoc |
典型使用场景
- 安装依赖的多步命令:一次写清更新、安装、清理三件事
- 生成多行配置文件:直接写进镜像,无需额外 COPY 源文件
- 写一段简短的维护脚本到镜像内固定路径
- 对照调试:把长脚本以自然格式呈现,方便审查改动
- 替代反斜杠续行:减少漏写反斜杠导致的命令被拆散问题
脚本与文件两种用法
脚本与文件两种用法
# syntax=docker/dockerfile:1
FROM debian:12-slim
# 多行脚本:安装与清理放在同一条指令里,减少层数
RUN <<EOF
set -eux
apt-get update
apt-get install -y --no-install-recommends ca-certificates curl
rm -rf /var/lib/apt/lists/*
EOF
# 直接把配置文件内容写进镜像
COPY <<EOF /etc/app/config.yaml
server:
port: 8080
host: 0.0.0.0
EOF
# 需要原样保留 $ 字符时给分隔符加引号,关闭变量展开
RUN <<'EOF'
echo 'price = $100'
EOF写法要点
| 要点 | 写法 | 说明 |
|---|---|---|
| 声明前端 | 首行 # syntax=docker/dockerfile:1 | 缺失则新语法不可用 |
| 脚本执行 | RUN <<EOF | 内容作为整体交给 shell |
| 文件写入 | COPY <<EOF /目标 | 内容直接成为文件内容 |
| 关闭展开 | <<'EOF' | 保留 $ 与反引号原意 |
| 结束标记 | 单独一行 EOF | 必须顶格,前后不能有多余空格 |
heredoc 内容不参与层缓存判断之外的额外处理,改动其中的一行会导致该指令层失效,与修改脚本文件的行为一致。
需要在镜像里保留一份可执行脚本文件时,可以在 heredoc 结束后执行安装命令,把内容落到目标路径并赋予执行权限。