一. 介绍
Dockerfile是一个包含用于组合镜像的命令的文本文档。可以在命令行中调用任何命令。docker可以通过Dockerfile文件来自动生成镜像。我们可以用docker build 命令来构建镜像。
Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以#
字符开头则被视为注释。可以在Docker文件中使用RUN
,CMD
,FROM
,EXPOSE
,ENV
等指令。
docker build:用 Dockerfile 构建镜像的命令关键词。
格式:常用的指令包括 -t 指定镜像的名字,-f 显示指定构建镜像的 Dockerfile 文件(Dockerfile 可不在当前路径下),如果不使用 -f,则默认将上下文路径下的名为 Dockerfile 的文件认为是构建镜像的 "Dockerfile" 。
例如:docker build -t busybox:v.0.1 . 其中 . 代表当前路径的Dockerfile。
二. 常用指令
1.FROM指令:From指令一般为第一个指令,用于为镜像文件指定基础镜像,后续的指令运行于此基准镜像所提供的运行环境。
格式:FROM <repository> [:<tag>]或FROM <repository> @<digest>
<repository>:指定作为base image 的名称
<tag>:base image 的标签,为可选项,省略时为latest。
2.MAINTAINER指令:用于让Dockerfile制作者提供本人的详细信息。一般将其放于FROM指令之后。
格式:MAINTAINER <author 's detail>:其中<author 's detail>可是任何文本信息,一般是作者名称及邮件地址。
3.LABEL指令:一般MAINTAINER指令已经被淘汰,所以我们常用LABEL指令代替。
例如:LABEL maintainer="xuye <xuye@test.com>"
4.COPY指令:用于从Docker主机复制文件至创建的新的镜像文件。
格式:COPY <src> ... <dest> 或 COPY ["<src>",...,"<dest>"]
其中<src>:要复制的源文件或目录,支持使用通配符。
<dest>:目标路径,即正在创建的image的文件系统路径。一般<dest>使用绝对路径。
注意:1)<src>必须是build上下文中的路径,不能是其父目录中的文件(一般跟Dockerfile同级)。
2)如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制。
3)如果指定了多个<src>,或者在<src>中使用了通配符,则<dest>必须是一个目录,且必须以 "/" 结尾。
4)如果<dest>事先不存在,它将被自动创建,包括其父目录路径。
eg:我们创建一个Dockerfile文件
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" copy ./yum.repos.d /data/yum.repos.d
我们用docker image ls查看是否已经存在busybox-v.0.1。
我们在用docker run 启动,看看/data目录下是否存在yum.repos.d目录。
5.ADD指令:ADD指令类似于COPY指令,ADD支持使用tar文件和URL路径。
注意:如果<src>为URL且<dest>不以 / 结尾,则<src>指定的文件将被下载并直接被创建为<dest>。如果<dest>以 / 结尾,则URL指定的文件将直接下载并保存为<dest>/<filename>
如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,类似于tar -x 命令,而通过URL获取到的tar文件将不会自动展开。
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" copy ./yum.repos.d /data/yum.repos.d ADD ./yum.repos.tar.gz /data/tar
6.VOLUME命令:用于在image中创建一个挂载点目录,以挂在Docker host上的卷或其他容器上的卷。
格式:VOLUME <mountpoint> 或 VOLUME ["<mountpoint>"]
如果挂载点目录路径下此前在文件中存在,docker run指令会在卷挂在完后,将此前的挂载卷的所有文件复制到新挂载的卷中。
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" copy ./yum.repos.d /data/yum.repos.d ADD ./yum.repos.tar.gz /data/tar VOLUME /data/volume
我们用docker inspect b1查看挂载信息:
7.EXPOSE指令:用于为容器打开指定要监听的端口以实现与外部通信。
格式:EXPOSE <port>[/<protocol>][<port>[/<protocol>]...]
<protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为tcp协议。
EXPOSE指令可以一次指定多个端口:EXPOSE 1121/udp 1122/tcp
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" COPY ./yum.repos.d /data/yum.repos.d COPY index.html /data/ ADD ./yum.repos.tar.gz /data/tar VOLUME /data/volume EXPOSE 80/tcp
8.ENV指令:用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其他指令(如ADD,COPY,ENV等)调用。
格式:ENV <key> <value> :只能设置一个变量
或
ENV <key> = <value>... 可以设置多个变量
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" COPY ./yum.repos.d /data/yum.repos.d ENV DATA=/data/ COPY index.html ${DATA} ADD ./yum.repos.tar.gz ${DATA}tar VOLUME ${DATA}volume EXPOSE 80/tcp
9.WORKDIR指令:相当于cd命令,进入到某个目录中进行操作。
10.RUN指令:用于指定docker build 过程中运行的程序,其可以是任何程序。
#this is my test Dockerfile FROM busybox:latest LABEL maintainer="xuy <xuy@test.com>" COPY ./yum.repos.d /data/yum.repos.d ENV DATA=/data/ \ NGX=nginx-1.17.3 \ DOWNLOADDIR=/usr/download COPY index.html ${DATA} ADD ./yum.repos.tar.gz ${DATA}tar RUN mkdir -p ${DOWNLOADDIR} ADD http://nginx.org/download/${NGX}.tar.gz ${DOWNLOADDIR} VOLUME ${DATA}volume EXPOSE 80/tcp WORKDIR ${DOWNLOADDIR} RUN tar -zxvf ${NGX}.tar.gz
11.CMD指令:类似于RUN指令,CMD指令也可以用于运行任何命令或应用程序,不过两者运行时间不同:
RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时。
CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止,不过CMD指令可以被docker run命令行选项覆盖。
Dockerfile文件中可以有多个CMD指令,但是只有最后一个指令生效。
12.ENTRYPOINT指令:类似于CMD指令的功能,用于为容器指定默认运行的程序,从而使得容器像是一个单独的可执行程序。
与CMD指令不同,由ENTRYPOINT指令启动的程序不会被docker run命令行指定的参数所覆盖,而且这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。
不过,docker run的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序。
13.USER指令:用于指定运行image时或运行Dockerfile中任何一个RUN,CMD或ENTRYPOINT指令指定的程序时的用户名或UID。默认情况下,container的运行身份为root用户。
格式:USER <UID>|<USERNAME>
14.HEALTHCHECK指令:用于检测主进程健康状态:
1)--interval=duration(default:30s) 间隔
2)--timeout=duration(default:30s)
3)--start-period=duration(default:0s) 等待多少时间,便于等主进程启动完。
4)--retries=N(default:3) 检查多少次。