Dockerfile 关键字以及部分关键字的区别
· 208 字 · 约 1 分钟
本文基于 Docker 官方 Dockerfile 参考 整理所有关键字,并说明几组容易混淆的指令之间的区别。
指令一览
Dockerfile 支持以下指令(按字母序):
| 指令 | 说明 |
|---|---|
| ADD | 添加本地或远程文件、目录(含 URL、压缩包自动解压) |
| ARG | 声明构建期变量 |
| CMD | 指定容器默认要运行的命令或参数 |
| COPY | 从构建上下文复制文件、目录到镜像 |
| ENTRYPOINT | 指定容器默认的可执行程序 |
| ENV | 设置环境变量(写入镜像,运行时可用) |
| EXPOSE | 声明容器监听的端口 |
| FROM | 从基础镜像开始新的构建阶段 |
| HEALTHCHECK | 配置容器健康检查 |
| LABEL | 为镜像添加元数据 |
| MAINTAINER | 指定镜像作者(已废弃,建议用 LABEL) |
| ONBUILD | 当本镜像被作为基础镜像使用时触发的指令 |
| RUN | 在构建时执行命令,产生新层 |
| SHELL | 设置 RUN、CMD、ENTRYPOINT 使用的默认 shell |
| STOPSIGNAL | 设置容器退出时发送的系统信号 |
| USER | 设置后续指令及运行时的用户/组 |
| VOLUME | 声明挂载点 |
| WORKDIR | 设置工作目录 |
约定上指令用大写,便于与参数区分;指令本身不区分大小写。Dockerfile 必须由 FROM 开头(前面只能有解析器指令、注释和全局 ARG),指令按顺序执行。
解析器指令(Parser directives)
解析器指令写在文件最上方,形式为 # directive=value,不参与构建层。每条指令只能出现一次,且必须出现在任何普通注释或构建指令之前。
syntax:指定使用的 Dockerfile 语法版本,例如# syntax=docker/dockerfile:1使用最新稳定语法。escape:设置转义符,默认\;在 Windows 下可设为`避免与路径中的\冲突。check:控制构建检查行为,如# check=skip=JSONArgsRecommended跳过指定检查,# check=error=true让检查失败时构建失败。
Shell 形式与 Exec 形式
RUN、CMD、ENTRYPOINT 都有两种写法:
- Shell 形式:
INSTRUCTION command param1 param2,通过 shell 执行,支持变量替换、多行续行等。 - Exec 形式:
INSTRUCTION ["executable","param1","param2"],按 JSON 数组解析,直接执行可执行文件,不经过 shell,因此不会自动做变量替换(若需要可显式写["sh","-c","echo $HOME"])。
Exec 形式中需用双引号,且反斜杠要转义(Windows 路径需写 \\)。
部分关键字的区别
ADD 和 COPY
- ADD:源可以是「构建上下文中的路径」或「URL」;若源是本地 tar 等归档,会自动解压到目标;行为较多,语义相对复杂。ADD 不支持
--from。 - COPY:只从构建上下文复制本地文件/目录,不解压、不拉 URL;支持
COPY --from=<阶段名|镜像>,可从命名构建阶段或外部镜像复制,多阶段构建时常用。语义单一,可预期性更好。
需要从构建上下文复制文件时,优先用 COPY;要从上一阶段或其它镜像复制时只能用 COPY –from=…;只有需要 URL 或自动解压归档时再用 ADD。
CMD 和 ENTRYPOINT
- CMD:定义容器默认的「命令或参数」。若 Dockerfile 中有多条 CMD,仅最后一条生效。
docker run末尾若带了参数,会覆盖整条 CMD。 - ENTRYPOINT:定义容器启动时「固定执行的可执行程序」。
docker run末尾的参数会作为参数传给 ENTRYPOINT,而不是替换 ENTRYPOINT。
常见用法:用 ENTRYPOINT 指定程序(如 ENTRYPOINT ["/app/server"]),用 CMD 提供默认参数(如 CMD ["--port","8080"]);运行时可覆盖 CMD,而 ENTRYPOINT 一般不变(除非用 --entrypoint)。
ARG 和 ENV
- ARG:仅构建期有效,用于
docker build时传入或 Dockerfile 内默认值;不会写入最终镜像,容器运行时无法使用。 - ENV:在构建期和运行期都有效,会写入镜像;容器内可通过环境变量访问。
在 FROM 之前的 ARG 只能用于 FROM 的镜像名/标签等;若要在阶段内再次使用该 ARG 的默认值,需在阶段内再写一行不带值的 ARG 变量名。
环境变量替换
在 Dockerfile 中可用 $var 或 ${var} 引用已通过 ENV 定义的变量;部分指令(如 WORKDIR、COPY、ADD、ENV、EXPOSE 等)由构建器做替换。RUN、CMD、ENTRYPOINT 若用 shell 形式,变量替换由 shell 完成;若用 exec 形式且未通过 shell,则不会做变量替换。
.dockerignore
与 .gitignore 类似,.dockerignore 可排除构建上下文中不需要的文件,减小上下文体积并避免敏感文件被 COPY/ADD 进镜像。
参考链接: