docker构建配置文件指令介绍
常用指令介绍
FROM
指令
FROM指令用于初始化一个新的构建阶段,并为后续指令设置基础镜像。因此,有效的Dockerfile必须从FROM指令开始。该镜像可以是任何有效的镜像(可以是公共镜像仓库库或者自定义镜像仓库)
语法:FROM < image>[:< tag> | @< digest>]
例如:
FROM mysql
FROM mysql:latest
FROM mysql:5.7
FROM mysql@sha:bf1c2b3e094fa12d9e87a
通常一个镜像都是以一个已存在的镜像(操作系统或其他镜像)为基础,在这个基础镜像之上叠加一到多个新的层,最终生成能满足特定用户需求的镜像。如果在一个Dockerfile中指定多条FROM指令,则一次可以生成多个镜像
MAINTAINER
– 已弃用
功能描述:填写镜像维护人名称,邮件地址可选
语法:MAINTAINER < name> < mail_adrr>
建议使用LABEL
指令,该指令在后续会介绍
RUN
功能描述:
语法:
RUN <command>(shell格式,命令在shell中运行,
默认情况下/bin/sh -c在Linux或cmd /S /C Windows 上运行)
RUN ["executable", "param1", "param2"](exec模式)
该RUN指令将在当前镜像之上执行所有命令,并提交结果。生成的提交镜像将用于下一步Dockerfile。
在shell形式中,可以使用(反斜杠)将一条RUN指令继续到下一行。例如,考虑以下两行:
例如:RUN yum install -y unzip openjdk \
&& unzip xx.zip \
&& yum remove unzip
注意
:要使用’/bin/sh’以外的其他shell,请使用exec形式传入所需的shell。例如, RUN ["/bin/bash", “-c”, “echo hello”]
注意
:与shell模式不同的是,exec模式不会调用命令shell。这意味着不会进行常规的包装处理。例如,RUN [ “echo”, “$PATH” ]将不会对进行变量替换$PATH。如果要进行shell处理,则可以使用shell形式或直接执行shell,例如:RUN [ “sh”, “-c”, “echo $PATH” ]。当使用exec模式并直接执行shell时(例如在shell表单中),是由shell进行环境变量处理,而不是docker。
CMD
功能描述:CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。
语法:
CMD ["executable","param1","param2"](exec模式,这是首选形式)
CMD ["param1","param2"](作为ENTRYPOINT的默认参数)
CMD command param1 param2(shell模式)
Dockerfile中只能有一条指令CMD指令。如果您列出多条CMD指令 则只有最后一条CMD会生效。
CMD的主要目的是为执行的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一条ENTRYPOINT指令。
注意
:如果CMD用于提供ENTRYPOINT 指令的默认参数,则CMD和ENTRYPOINT指令均应使用JSON数组格式指定。
LABEL
LABEL指令将元数据添加到镜像。LABEL是键值对。要在LABEL值中包含空格,需要使用引号和反斜杠。
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一些用法示例:
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."
一个镜像可以有多个标签,也可以在一行上指定多个标签。在Docker 1.10之前的版本中,这减小了最终映像的大小,但是情况不再如此。您仍然可以通过以下两种方式之一选择在一条指令中指定多个标签:
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
你的镜像将继承基础或父镜像(FROM指令中的镜像)中包含的LABEL。如果标签已经存在但具有不同的值,则最上层的值将覆盖任何先前设置的值。
要查看图像的标签,请使用docker inspect命令。
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
EXPOSE指令通知Docker容器在运行时监听指定的网络端口。您可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。
EXPOSE指令实际上并未发布端口。它充当构建镜像的人与运行容器的人之间的一种文档约定,说明对外暴露哪些端口的信息。要在运行容器时实际发布端口,请使用-p
标记docker run
对外暴露和映射一个或多个端口,或者使用-P标记发布所有公开的端口并将它们映射到高阶端口,默认情况下,EXPOSE假定为TCP。您还可以指定UDP,例如:
EXPOSE 80/udp
ENV
ENV <key> <value>
ENV <key>=<value> ...
例如:
ENV MYSQL_USER=root
ENV MYSQL_USER root
ENV指令将环境变量key设置为value。此值将在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
该ENV指令有两种形式。第一种形式,ENV 将一个环境变量设置为一个值。第一个空格之后的整个字符串将被视为value-包括空格字符。该值将为其他环境变量解释,因此如果不对引号字符进行转义,则将其删除。
第二种形式ENV key=value …允许一次设置多个变量。请注意,第二种形式在语法中使用等号(=),而第一种形式则不使用等号(=)。像命令行解析一样,引号和反斜杠可用于在值中包含空格。
例如:
ENV env1="env 1" env2=env\ 2\ key
env3=env3
等价于
ENV env1 env 1
ENV env2 env 2 key
ENV env3 env3
ENV从构建后的镜像运行容器时,使用设置的环境变量将保留。可以使用docker inspect查看环境变量,使用docker run --env key=value来改变这些预设好的环境变量对应的值
ADD
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
(此格式对于包含空格的路径是必需的)
注意
:此–chown功能仅支持在Linux平台上构建镜像的Dockerfile上,而在Windows平台上不起作用。由于用户和组所有权概念不会在Linux和Windows之间转换,因此使用/etc/passwd和/etc/group将用户名和组名转换为ID的使用限制了此功能仅对基于Linux OS的容器可用。
ADD指令用于复制文件到镜像上,支持本地目录或远程文件URL ,并将它们添加到镜像的文件系统的dest中。
ADD test* /usr/images/ # 添加所有以test为文件头的文件到/usr/images/下
src可以指定多个资源,但是如果它们是文件或目录,则将其路径解释为相对于构建上下文源的路径。
dest是一个绝对路径,或目标镜像中WORKDIR的相对路径。
ADD a.file tmp/ # 添加a.file 到`WORKDIR`/tmp/下
ADD b.flie /tmp/ # 添加 /absolutb.file到/tmp/目录下
COPY
语法:COPY org dest
复制本地主机org目录或文件到镜像中的desc,desc不存在时会自动创建。
ENTRYPOINT
语法:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1,param2 会在shell中执行。
用于配置容器启动后执行的命令,这些命令不能被docker run提供的参数覆盖。和CMD一样,每个Dockerfile中只能有一个ENTRYPOINT,当有多个时最后一个生效。
VOLUME
语法: VOLUME ["/data"]
作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。
USER
格式为:USER username
指定容器运行时的用户名,后续的RUN也会使用指定的用户。
除了使用已有的系统用户(通常是root、deamon等)之外,我们更多的是使用自己创建的用户,因为这样更安全。在USER命令之前可以使用RUN命令创建需要的用户。
例如:RUN groupadd -r mysql && useradd -r -g mysql mysql
WORKDIR
语法: WORKDIR path
为容器运行指定工作目录,可以使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于之前的命令指定路径。