Dockerfile 参考文档¶
Dockerfile 是用于构建 Docker 镜像的文本文件,包含了一系列构建镜像所需的指令。
Format¶
解析器指令(Parser Directives)¶
解析器指令是可选的,会影响 Dockerfile 中后续行的处理方式。解析器指令不向构建中添加层,也不显示为构建步骤。
解析器指令被写成一种特殊类型的注释,格式为 # directive=value。一个指令只能使用一次。
是 Dockerfile 中的一种特殊注释,用于在 Docker 开始解析 Dockerfile 中的指令之前,指示 Docker 引擎如何解释这个 Dockerfile 文件。
可以把它们理解为给 Docker 构建器的前置设置或选项。
关键特性¶
1.格式特殊
它们看起来像注释,但语法有严格要求。
- 必须是
# directive=value的形式 - 必须放在 Dockerfile 的最顶端,在任何其他注释或指令之前
#号和指令名之间不能有空格,但指令名和值之间的=号前后可以有空格- 字母必须小写
2.位置敏感
一旦 Dockerfile 中出现了第一条非解析指令的真正指令(如 FROM, RUN 等)或普通注释,之后的所有内容都不能再被识别为解析器指令,它们会被当作普通注释处理。
3.作用域
解析器指令只对当前这个 Dockerfile 有效。
支持的解析器指令¶
Dockerfile 支持以下解析器指令:
syntax(语法指令)escape(转义符指令)check(检查指令)
syntax(语法指令)¶
- 用途: 指定用于构建此 Dockerfile 的 Dockerfile 前端解析器。
- 值: 是一个指向包含解析器的 Docker 镜像的地址。
为什么需要它?
- 使用实验性功能:允许在官方支持新功能之前,使用这些新功能。例如,当
RUN --mount还是实验性功能时,就需要通过syntax指令来启用。 - 使用第三方增强功能:社区或第三方可能提供了功能更丰富或不同的构建器。
示例
escape(转义符指令)¶
- 用途: 指定 Dockerfile 中使用的转义字符。这在 Windows 系统中特别有用,因为 Windows 路径中大量使用
\。 - 默认值:
\ - 可选值:
`(反引号)
为什么需要它?
- 在默认转义符是
\的系统中,如果你需要在RUN命令中使用\作为路径分隔符(如 Windows),就会产生冲突。这时可以将其设置为反引号`。
示例
| Docker | |
|---|---|
check(检查指令)(since Dockerfile v1.8.0)¶
- 用途: 主要作用是控制 Docker 构建器(Builder)在解析 Dockerfile 时是否进行严格的语法和选项检查。
- 默认行为: 运行所有检查,但如果检查失败(发现问题),仅将其视为警告(Warning),而不会导致构建失败。
- 语法:
# check=value -
选项: 指令主要通过两个选项来配置:
skip和error。 -
跳过检查:
skip选项
用于禁用特定的检查项或全部检查。禁用特定检查,要跳过多个检查,用逗号分隔它们
| Docker | |
|---|---|
- 将警告视为错误:
error选项
用于改变构建失败的条件。默认情况下,检查失败只是警告,构建仍会成功。
| Docker | |
|---|---|
- 组合使用选项: 同时使用
skip和error选项,用分号;分隔它们。
| Docker | |
|---|---|
Environment Replacement(环境变量替换)¶
1. 基本语法¶
在 Dockerfile 中,使用 ENV 指令声明的环境变量可以通过以下方式引用。
$variable_name${variable_name}(推荐,尤其适用于变量名与其他字符连接的情况,如 ${name}_bar)
2. 高级 Bash 风格修饰符¶
Dockerfile 支持一些类似 Bash 的变量替换语法:
默认值替换
| Bash | |
|---|---|
模式匹配删除
| Bash | |
|---|---|
模式替换
| Bash | |
|---|---|
注意:
pattern是通配模式,?匹配单个字符,*匹配任意多个字符- 转义使用
\?和\* - 这些功能需要在使用
# syntax=docker/dockerfile-upstream:master等预览语法时才可用
3. 转义¶
在变量前加反斜杠 \ 可以将其视为普通字符,而不是变量。
| Bash | |
|---|---|
4. 作用范围与时机¶
- 一条指令内的变量值固定:一条指令中对同一变量的所有引用,都会使用该指令开始执行时的值。
- 后续指令生效:只有在
ENV指令之后的下一条指令开始,新设置或修改的环境变量值才会生效。
| Docker | |
|---|---|
5.支持变量替换的指令¶
以下指令由 Docker 构建器(Builder)处理变量替换:
ADD, COPY, ENV, EXPOSE, FROM, LABEL, STOPSIGNAL, USER, VOLUME, WORKDIR,以及 ONBUILD 与上述指令结合时。
特殊说明 RUN, CMD, ENTRYPOINT:
这三个指令的变量替换不是由构建器处理,而是由命令shell(如 /bin/sh)处理的。
Shell and exec form¶
RUN, CMD, 和 ENTRYPOINT 指令都有两种写法
1.Exec 形式 (JSON 数组形式)¶
语法: INSTRUCTION ["executable", "param1", "param2", ...]
优点:
- 避免 shell 的字符串处理,参数清晰明确。
- 不会自动调用命令 shell。
- 是设置
ENTRYPOINT的首选方式。
重要特性:
- 不会自动进行变量替换! 因为不调用 shell。
RUN ["echo", "$HOME"]会直接输出字符串$HOME,而不是家目录路径。 - 必须使用双引号。
- 需要转义反斜杠(尤其在 Windows 路径中)。
- 错误: RUN ["c:\windows\system32\tasklist.exe"]
- 正确: RUN ["c:\windows\system32\tasklist.exe"]
如何在 Exec 形式中使用变量替换?
需要显式地调用一个 shell:
2.Shell 形式¶
语法: INSTRUCTION command param1 param2
优点:
- 写法简单直观,易于阅读。
- 自动调用命令 shell(默认是
/bin/sh -c)。 - 自动进行变量替换、通配符扩展等所有 shell 功能。
- 可以使用反斜杠
\换行,方便书写长命令。 - 支持 Heredoc 语法,非常适合嵌入多行脚本。
| Docker | |
|---|---|
3.选择哪种形式?¶
使用 Shell 形式当:
- 需要 shell 功能(变量替换、管道、重定向等)。
- 命令简单,追求可读性。
使用 Exec 形式当:
- 你不需要 shell 功能,希望避免 shell 引起的意外行为。
- 你需要为 ENTRYPOINT 指定确切的参数。
- 你希望容器进程能够正确接收 Unix 信号(如 SIGTERM),因为 shell 形式会默认让 shell 成为 PID 1 的进程。
4.更改默认 Shell¶
可以使用 SHELL 指令改变后续所有 Shell 形式指令所使用的默认 shell。
Dockerfile 基本指令¶
指令列表¶
Dockerfile 支持如下指令:
| 指令 | 说明 |
|---|---|
FROM |
指定基础镜像,用于后续的指令构建,centos,ubuntu |
MAINTAINER |
指定Dockerfile 的作者/维护者,姓名+邮箱。(已弃用,推荐使用 LABEL 指令) |
LABEL |
添加镜像的元数据,使用键值对的形式 |
RUN |
构建时需要运行的命令,build 时运行 |
CMD |
指定容器创建时的默认命令(可以被覆盖),run 时执行 |
ENTRYPOINT |
设置容器创建时的主要命令(不可被覆盖) |
EXPOSE |
声明容器运行时监听的特定网络端口 |
ENV |
构建时设置环境变量 |
ADD |
将文件、目录或远程 URL 复制到镜像中,会解压缩文件 |
COPY |
将文件或目录复制到镜像中 |
VOLUME |
为容器创建挂载点或声明卷 |
WORKDIR |
设置后续指令的工作目录 |
USER |
指定后续指令的用户上下文 |
ARG |
定义在构建过程中传递给构建器的变量,可以使用 "docker build" 命令设置 |
ONBUILD |
当该镜像被用作另一个构建过程的基础时,添加触发器 |
STOPSIGNAL |
设置发送给容器以退出的系统调用信号 |
HEALTHCHECK |
定义周期性检查容器健康状态的命令 |
SHELL |
覆盖Docker 中默认的 shell,用于 RUN、CMD 和 ENTRYPOINT 指令 |
基本规则¶
- 指令不区分大小写,但建议大写,以区分指令与参数
- 执行从上到下顺序执行
#开头的行表示注释,构建时不创建镜像层- 每个指令都会创建一个新的镜像层并提交
Dockerfile 例⼦¶
| Docker | |
|---|---|