格式
- 指令 参数
- Dockerfile 无视大小写,但是代码规范中要求指令名大写,参数小写
- Dockerfile是按顺序执行的
- Dockerfile中第一个有效指令必须为
From
,用来指定基础镜像
常用指令
FROM
FROM 指令是最为重要的一个,并且必须为 Dockerfile 文件开篇的第一个非注释行,用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像提供的运行环境
这个镜像可以是任何可用镜像,默认情况下 docker build 会从本地仓库找指定的镜像文件,如果不存在就会从 Docker Hub 上拉取
语法:
1 | # 不指定版本的情况下默认为 latest |
MAINTAINER(弃用)
Dockerfile 的制作者提供的本人详细信息
Dockerfile 不限制 MAINTAINER 出现的位置,但是推荐放到 FROM 指令之后
语法:
1 | MAINTAINER <name> |
name 可以是任何文本信息,一般用作者名称或者邮箱
LABEL
给镜像指定各种元数据
语法
1 | LABEL <key>=<value> <key>=<value> <key>=<value> ... |
一个 Dockerfile 可以写多个 LABEL,但是不推荐这么做,Dockerfile 每一条指令都会生成一层镜像,如果 LABEL 太长可以使用 \
符号换行。构建的镜像会继承基础镜像的 LABEL,并且会去掉重复的,但如果值不同,则后面的值会覆盖前面的值
COPY
用于从宿主机复制文件到创建的新镜像文件
语法:
1 | COPY <src>...<dest> |
ADD
基本用法和COPY一样,ADD支持使用 TAR 文件和 URL 路径
语法:
1 | ADD <src>...<dest> |
规则:
- 和 COPY 规则相同
- 如果
<src>
为URL 并且<dest>
没有以/
结尾,则<src>
指定的文件将被下载到<dest>
- 如果
<src>
是一个本地系统上压缩格式的tar
文件,它会展开成一个目录;但是通过 URL 获取的tar
文件不会自动展开 - 如果
<src>
有多个,直接或间接使用了通配符指定多个资源,则<dest>
必须是目录并且以/
结尾
WORKDIR
用于为 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指定设定工作目录,只会影响当前 WORKDIR 之后的指令
语法:
1 | WORKDIR <dirpath> |
在 Dockerfile 文件中,WORKDIR 可以出现多次,路径可以是相对路径,但是它是相对于前一个 WORKDIR 指令指定的路径
另外,WORKDIR 可以是 ENV 指定定义的变量
ENTRYPOINT
类似于 CMD 指令功能,用于给容器指定默认运行程序
语法:
1 | ENTRYPOINT <command> |
和 CMD 不同的是 ENTRYPOINT 启动的程序不会被 docker run 命令指定的参数所覆盖,而且,这些命令行参数会被当做参数传递给 ENTRYPOINT 指定的程序(但是,docker run 命令的 --entrypoint
参数可以覆盖 ENTRYPOINT)
docker run 命令传入的参数会覆盖 CMD 指令的内容并且附加到 ENTRYPOINT 命令最后作为其参数使用
同样,Dockerfile 中可以存在多个 ENTRYPOINT 指令,但是只有最后一个会生效
Dockerfile 中如果既有 CMD 又有 ENTRYPOINT,并且 CMD 是一个完整可执行命令,那么谁在最后谁生效
ENV
用来给镜像定义所需要的环境变量,并且可以被 Dockerfile 文件中位于其后的其他指令(如 ENV
、ADD
、COPY
等)所调用,调用格式:$variable_name
或者 ${variable_naem}
语法:
1 | ENV <key> <value> |
第一种格式中,<key>
之后的所有内容都会被视为 <value>
的组成部分,所以一次只能设置一个变量
第二种格式可以一次设置多个变量,如果 <value>
当中有空格可以使用 \
进行转义或者对 <value>
加引号进行标识;另外 \
也可以用来续行
ARG
用法同 ENV
语法:
1 | ARG <name> [=<default value>] |
指定一个变量,可以在 docker build
创建镜像的时候,使用 --build-arg <varname>=<value>
来指定参数
常见问题
# COPY 与 ADD 命令的异同
1、COPY 和 ADD 命令不能拷贝上下文之外的本地文件
对于 COPY 和 ADD 命令来说,如果要把本地的文件拷贝到镜像中,那么本地的文件必须是在上下文目录中的文件。因为在执行 build 命令时,docker 客户端会把上下文中所有文件发给 docker daemon。考虑 docker 客户端和 docker daemon 不在同一台机器上的情况,build 命令只能从上下文中获取文件。如果在 Dockerfile 的 COPY 和 ADD 命令中引用了上下文中没有的文件,则会报错。
2、可以认为 ADD 是 COPY 的加强版
ADD 命令支持将远程 URL 的资源加入到镜像的文件系统。
当要读取 URL 远程资源的时候,并不推荐使用 ADD 指令,而是推荐使用 RUN 指令,在 RUN 指令中执行 wget
或 curl
命令。
注意:
- 对于从远程 URL 获取资源的情况,由于 ADD 指令不支持认证,如果从远程获取资源需要认证,则只能使用
RUN wget
或RUN curl
替代。 - 如果源路径的资源发生变化,则该 ADD 指令将使 Docker Cache 失效,Dockerfile 中后续的所有指令都不能使用缓存。因此 尽量将 ADD 指令放在 Dockerfile 的后面。
- 源路径可以有多个
- 源路径是相对于执行build的相对路径
- 源路径如果是本地路径,必须是 build 上下文中的路径
- 源路径如果是一个目录,则该目录下的所有内容都将被加入到容器,但是该目录本身不会
- 目标路径必须是绝对路径,或相对于
WORKDIR
的相对路径 - 目标路径如果不存在,则会创建相应的完整路径
- 目标路径如果不是一个文件,则必须使用
/
结束 - 路径中可以使用通配符