Dockerfile中有许多指令,详细且全面的介绍参考官方文档
FROM
指令格式:
FROM <image> [AS <name>]或者
FROM <image>[:<tag>] [AS <name>]或者
FROM <image>[@<digest>] [AS <name>]FROM指令设置一个基础镜像,让后面的指令可以在一个镜像中运行,可以是任何在镜像库中存在的镜像,一般作为是Dockerfile的第一条指令
ARG是唯一可以放在FROM之前的指令FROM可以在同一个Dockerfile里面出现多次tag和digest参数不是必填的,如果不填默认是latest也就是最后的版本
了解FROM和ARG的交互方式
FROM指令可以使用在FROM之前声明的任何ARG变量
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extrasFROM之前声明的变量如果想在FROM之后再次被其他指令使用需要重新声明
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_versionRUN
RUN指令用于指定镜像被构建时要运行的命令。有两种格式:
RUN <command> (shell格式,命令在shell中执行)
RUN ["executable", "param1", "param2"] (exec格式)可以用反斜杠\表示换行
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'等同于
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'CMD
CMD指令用于指定一个容器启动时要运行的命令。有三种格式:
CMD ["executable","param1","param2"] (exec格式,首选)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell格式)如docker run命令可以覆盖CMD指令,如果在Dockerfile文件中指定了CMD指令,而同时在docker run命令行中指定了要运行的命令,命令行的命令会覆盖Dockerfile中的CMD指令。
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 multi.label1="value1" \
multi.label2="value2" \
other="value3"可以使用 docker inspect 命令查看这些标签
MAINTAINER (deprecated)
指定作者信息,指令格式:
MAINTAINER <name>官方推荐使用LABEL指令添加作者信息而不是使用MAINTAINER指令,这样就可以使用docker inspect命令查看这些信息
LABEL maintainer="SvenDowideit@home.org.au"EXPOSE
开放容器内的端口给外部,可以指定端口是在TCP还是UDP上侦听,如果未指定协议,则默认值为TCP。 这个指令只是开放容器内部端口给外部,并不能指定宿主的映射端口,如果需要配置映射关系需要在 docker run 用 -p 指定端口映射关系。指令格式
EXPOSE <port> [<port>/<protocol>...]例如开放容器内80的TCP和UDP,格式是一行,当然也可以写成两行
EXPOSE 80/tcp
EXPOSE 80/udpENV
ENV指令用来在镜像构建过程中设置环境变量,后续的RUN可以使用它所创建的环境变量。 指令格式:
ENV <key> <value>
ENV <key>=<value> ...新建一个Dockerfile添加如下内容
FROM ubuntu
ENV env varible生成镜像,运行容器,会看到声明的环境变量
[root@Charlie env]# docker build -t test/env .
···
[root@Charlie env]# docker run -it test/env /bin/bash
root@3a27a7e4598f:/# env
···
env=varible
···如果在 docker run -e 指定了某个环境变量值,就会覆盖Dockerfile中原先的配置值
[root@Charlie env]# docker run -it -e "env=run_command" test/env /bin/bash
root@0cf1a2954574:/# env
···
env=run_command
···ADD
是将宿主机文件复制到镜像中,指令格式:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]<dest>路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径; <src>可以是一个本地文件或者是一个本地压缩文件,还可以是一个url; 如果把<src>写成一个url,那么ADD就类似于wget命令。 例如将构建目录下的 test.txt 文件复制到镜像中 /usr/local/test.txt 文件
ADD test.txt /usr/local/test.txt文件源也可以使用url的格式,例如下载最新的wordpress压缩包 latest.zip 到/usr/local命名为wordpress.zip
ADD https://wordpress.org/latest.zip /usr/local/wordpress.zip如果将本地归档文件(tar archive),合法的归档文件(gzip、bzip2、xz)指向到文件夹,Docker会自动解压,下面会将latest.tar.gz文件自动解压到镜像的/usr/local/wordpress/目录下
ADD latest.tar.gz /usr/local/wordpress/COPY
是将宿主机文件复制到镜像中,与ADD功能相同,区别是ADD可以使用url下载远程服务器的文件复制到镜像中,ADD还可以自动解压某些压缩包,这两个功能COPY都不可以。指令格式:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (this form is required for paths containing whitespace)ENTRYPOINT
CMD指令用于指定一个容器启动时要运行的命令。指令格式:
ENTRYPOINT ["executable", "param1", "param2"] (exec格式,首选)
ENTRYPOINT command param1 param2 (shell格式)与CMD功能类似,只能写一条,如果写了多条,只有最后一条生效,上文提到在运行docker run命令行时如果指定了要运行的命令会覆盖Dockerfile中的CMD指令,差异就在这里ENTRYPOINT指令是无法被docker run命令行指定的指令覆盖的。 如果在Dockerfile中同时写了ENTRYPOINT和CMD,它们两个会互相覆盖,谁在最后谁生效。 ENTRYPOINT 和CMD不同组合的执行情况(这里展示效果不好可以直接去官网查看):
No ENTRYPOINT
ENTRYPOINT exec_entry p1_entry
ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD
error, not allowed
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”]
exec_cmd p1_cmd
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”]
p1_cmd p2_cmd
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd
/bin/sh -c exec_cmd p1_cmd
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
VOLUME
VOLUME指令相当于创建一个挂载点,保存数据到容器挂载的这个文件夹。指令格式:
VOLUME ["/data"]参数可以是个Json串,
VOLUME ["/var/log/"]或者一个或多个值
VOLUME /var/log
VOLUME /var/log /var/db当容器中的数据需要持久化的时候需要使用这个命令。
USER
设置启动容器的用户名(或者UID)和用户组(或者GID)来运行Dockerfile里面RUN, CMD and ENTRYPOINT 指令。指令格式:
USER <user>[:<group>]
USER <UID>[:<GID>]WORKDIR
WORKDIR指令设置RUN, CMD, ENTRYPOINT, COPY 和 ADD指令的工作目录,如果设置的工作目录不存在会自动创建。指令格式:
WORKDIR /path/to/workdirWORKDIR指令可以设置多次,下面例子的pwd命令执行结果是 /a/b/c:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwdWORKDIR指令还可以解析ENV指令设置的环境变量,下面例子pwd命令执行结果是/path/$DIRNAME
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwdARG
ARG指令设置变量,指令格式:
ARG <name>[=<default value>]在docker build创建镜像的时候,使用 --build-arg <varname>=<value>来指定参数,如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning
[Warning] One or more build-args [foo] were not consumed.一个Dockerfile文件中可以有一个或者多个ARG定义的变量,如下的例子ARG定义的参数都是可用的
FROM busybox
ARG user1
ARG buildno
···也可以给变量设置一个默认值
FROM busybox
ARG user1=someuser
ARG buildno=1
···ONBUILD
当一个Dockerfile文件中使用了ONBUILD指令,生成了镜像A,这个镜像A中是不执行ONBUILD指令的内容的,但是如果镜像B是以镜像A作为基础镜像时,镜像B中就会执行这个ONBUILD指令。指令格式:
ONBUILD [INSTRUCTION]STOPSIGNAL
STOPSIGNAL命令是的作用是当容器退出时给系统发送什么样的指令。指令格式:
STOPSIGNAL signalHEALTHCHECK
指令格式:
HEALTHCHECK [OPTIONS] CMD command (通过在容器内运行命令检查容器健康状况)
HEALTHCHECK NONE (在基础镜像中取消健康检查)HEALTHCHECK命令只能出现一次,如果出现了多次,只有最后一个生效。 CMD后面可以接以下选项:
- –interval=DURATION (default: 30s)
- –timeout=DURATION (default: 30s)
- –start-period=DURATION (default: 0s)
- –retries=N (default: 3)
返回值:
- 0: success - 表示容器是健康的
- 1: unhealthy - 表示容器已经不能工作了
- 2: reserved - 保留值
如下例子:健康检查命令是:curl -f http://localhost/ || exit 1;两次检查的间隔时间是5秒;命令超时时间为3秒。
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1SHELL
指令格式:
SHELL ["executable", "parameters"]SHELL指令允许覆盖用于shell形式的命令的默认shell 。Linux上的默认shell是["/bin/sh", “-c”],而在Windows上[“cmd”, “/S”, “/C”]。 SHELL指令必须以JSON格式写入Dockerfile; SHELL指令可以多次出现。每条SHELL指令都会覆盖所有先前的SHELL指令,并影响所有后续指令。