Dockerfile是Docker用来构建镜像的文本文件,包括自定义的指令和格式。可以通过docker build命令从Dockerfile中构建镜像。用户可以通过统一的语法命令来根据需求进行配置,通过这份统一的配置文件,在不同的文件上进行分发,需要使用时就可以根据配置文件进行自动化构建,这解决了开发人员构建镜像的复杂过程。
在Dockerfile中,指令(INSTRUCTION)不区分大小写,但是为了与参数区分,推荐大写。Docker会顺序执行Dockerfile中的指令,第一条指令必须是FROM指令,它用于指定构建镜像的基础镜像。在Dockerfile中以#开头的行是注释,而在其他位置出现的#会被当成参数。
Dockerfile中的指令有FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOING、VOLUME、USER、WORKDIR、ONBUILD,错误的指令会被忽略。下面将详细讲解一些重要的Docker指令。
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
FROM指令的功能是为后面的指令提供基础镜像,因此Dockerfile必须以FROM指令作为第一条非注释指令。从公共镜像库中拉取镜像很容易,基础镜像可以选择任何有效的镜像。在一个Dockerfile中FROM指令可以出现多次,这样会构建多个镜像。tag的默认值是latest,如果参数image或者tag指定的镜像不存在,则返回错误。
MAINTAINER <name>
指定作者,新版docker中使用LABEL指明
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号
如下:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
为镜像指定标签,LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖
ADD <src> <dest>
ADD与COPY指令在功能上很相似,都支持复制本地文件到镜像的功能,但ADD指令还支持其他功能。src可以是指向网络文件的URL,此时若dest指向一个目录,则URL必须是完全路径,这样可以获得网络文件的文件名filename,该文件会被复制添加到dest/filename。
比如 ADD http://example.cn/config.property / 会创建文件/config.property。
src还可以指向一个本地压缩归档文件,该文件会在复制到容器时会被解压提取,如ADD example.tar.gz /。但是若URL中的文件为归档文件则不会被解压提取。
ADD 和 COPY指令虽然功能相似,但一般推荐使用COPY,因为COPY只支持本地文件,相比ADD
COPY <src> <dest>
COPY指令复制所指向的文件或目录,将它添加到新镜像中,复制的文件或目录在镜像中的路径是dest。src所指定的源可以有多个,但必须是上下文根目录中的相对路径。不能只用形如 COPY …/something /something这样的指令。此外,src可以使用通配符指向所有匹配通配符的文件或目录,例如,COPY home* /mydir/ 表示添加所有以"hom"开头的文件到目录/mydir/中。
dest可以是文件或目录,但必须是目标镜像中的绝对路径或者相对于WORKDIR的相对路径(WORKDIR即Dockerfile中WORKDIR指令指定的路径,用来为其他指令设置工作目录)。若dest以反斜杠/结尾则其指向的是目录;否则指向文件。src同理。若dest是一个文件,则src的内容会被写到dest中;否则src指向的文件或目录中的内容会被复制添加到dest目录中。当src指定多个源时,dest必须是目录。如果dest不存在,则路径中不存在的目录会被创建。
EXPOSE <port> [<port>/<protocol>...]
用于为容器打开指定要监听的端口以实现与外部通信,这个只是声明,真正要暴露这个端口需要再构建容器的时候使用"-P"选项。
设置环境变量,无论是接下来的指令(如ENV、ADD、COPY等,其调用格式为 v a r i a b l e n a m e 或 variable_name或 variablename或{variable_name}),还是在容器中运行的程序,都可以使用这里定义的环境变量。
ENV <key> <value>
ENV <key>=<value> ...
两者的区别就是第一种是一次设置一个,第二种是一次设置多个。
用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指令设定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,它的路径是相对此前一个WORKDIR指令指定的路径。另外,WORKDIR也可调用由ENV指定定义的变量。
WORKDIR <工作目录路径>
用于指定执行后续命令的用户和用户组,这里只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。在USER命令之前可以使用RUN命令创建需要的用户。
默认情况下,容器的运行身份为root用户。
# 可以指定用户名或者UID,组名或者GID
USER <user>[:<group>]
USER <UID>[:<GID>]