docker系列—Dockerfile详解

介绍

镜像的制作方式有两种

  1. 基于容器制作,但这样的镜像不利于维护,不适合线上使用。
  2. 另一种就是就是要介绍的Dockerfile,Dockerfile就是构建镜像的源代码,当时和我们编写程序的源代码不同,Dockerfile是一些命令的组合。

简要概括Dockerfile的作用:可以让用户个性化定制Docker镜像。因为不同的工作环境需求不同,网络上已存在的镜像不能完全满足自己的需求,此时就需要利用Dockerfile来构建自己可以满足自己需求的镜像。

格式

  1. Dockerfile整体就两类语句组成:
    • 注释信息,以 # 标识的行为注释行
    • 指令参数,一行一个指令。
  2. Dockerfile文件名首字母必须大写。
  3. Dockerfile指令不区分大小写,但是为方便和参数做区分,通常指令使用大写字母。
  4. Dockerfile中指令按顺序从上至下依次执行。
  5. Dockerfile中第一个非注释行必须是FROM指令,用来指定制作当前镜像依据的是哪个基础镜像。
  6. Dockerfile中需要调用的文件必须跟Dockerfile文件在同一目录下,或者在其子目录下,父目录或者其它路径无效。

指令集

FROM

  • FROM指令必须为Dockerfile文件开篇的第一个非注释行,用于指定构建镜像所使用的基础镜像,后续的指令运行都要依靠此基础镜像所提供的的环境(简单说就是假如Dockerfile中所引用的基础镜像里面没有mkdir命令,那后续的指令是没法使用mkdir参数的。)

  • 实际使用中,如果没有指定仓库,docker build会先从本机查找是否有此基础镜像,如果没有会默认去Docker Hub Registry上拉取,再找不到就会报错。

语法

FROM [--platform=<platform>] <image> [AS <name>]
or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

scratch 是最基础的一个空白镜像。 下面是官方的centos的Dockerfile 在这里插入图片描述
RUN

  • RUN指令将在当前镜像的顶部中执行所有命令,并提交结果,生成的镜像将用于下一条指令。
  • RUN下一次构建期间,指令缓存不会自动失效。类似指令的缓存 RUN apt-get dist-upgrade -y将在下一个构建中重用。RUN指令的缓存可以通过使用–no-cache 标志来使无效,例如docker build --no-cache。

语法

shell形式,命令在shell中运行,默认情况下/bin/sh -c在Linux或cmd /S /CWindows 上运行

RUN <command>

参数是一个JSON格式的数组,其中"executable"为要运行的命令,后面的"paramN"为传递给命令的选项或参数。此格式指定的命令不会以"/bin/sh-c"来发起,也就是直接由内核创建,因此不具备shell特性,类似于RUN [ "echo", "$HOME" ],是无法识别 $ 的;如果想要依赖shell特性,可以替换命令为这样的格式[ "/bin/sh", "-c", "echo $HOME" ]

RUN ["executable", "param1", "param2"]

CMD

  • 指定启动容器的默认要运行的程序,也就是PID为1的进程命令,且其运行结束后容器也会终止。如果不指定,默认是bash。
  • CMD指令指定的默认程序会被docker run命令行指定的参数所覆盖。
  • Dockerfile中可以存在多个CMD指令,但仅最后一个生效。因为一个docker容器只能运行一个PID为1的进程。
  • 类似于RUN指令,也可以运行任意命令或程序,但是两者的运行时间点不同,RUN指令运行在docker build的过程中,而CMD指令运行在基于新镜像启动容器(docker run)时。

语法

前两种语法格式同RUN指令。第一种用法对于CMD指令基本没有意义,因为它运行的程序PID不为1。

CMD command param1 param2

CMD ["executable","param1","param2"](exec形式,这是首选形式)

第三种则需要结合ENTRYPOINT指令使用,CMD指令后面的命令作为ENTRYPOINT指令的默认参 数。如果docker run命令行结尾有参数指定,那CMD后面的参数不生效。

CMD ["param1","param2"](作为ENTRYPOINT的默认参数)

LABEL

  • 同docker run -l
  • 用户可以为镜像指定各种元数据(键值对的格式)。

语法

可以在一行或者使用 \ 来拼接,来减少镜像的层,最终减小镜像的大小。

LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL multi.label1="value1" multi.label2="value2" other="value3"
or
LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"

MAINTAINER
已弃用,LABEL要灵活的多。

EXPOSE

  • 通知Docker容器在运行时监听指定的网络端口。可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。
  • docker run --expose

语法

EXPOSE <port> [<port>/<protocol>...]

示例

EXPOSE 80/tcp
EXPOSE 80/udp

ENV

  • ENV指令将环境变量设置为<key><value>。此值将在构建阶段中所有后续指令的环境中使用。调用格式为$variable_name或者${variable_name}
  • docker run -e

语法

ENV <key> <value>
ENV <key>=<value> ...
  1. 第一种形式,ENV<key> <value>会将一个变量设置为一个值。第一个空格之后的整个字符串将被视为-包括空格字符。该值将为其他环境变量解释,因此如果不对引号字符进行转义,则将其删除。
  2. 第二种形式ENV <key>=<value> ...允许一次设置多个变量。请注意,第二种形式在语法中使用等号(=),而第一种形式则不使用等号(=)。像命令行解析一样,引号和反斜杠可用于在值中包含空格。
  3. 定义多个变量时,建议使用第二种方式,因为Dockerfile中每一行都是一个镜像层,构建起来比较吃资源。

ADD

  • ADD指令跟COPY类似,不过它还支持使用tar文件和URL路径。
  • 当拷贝的源文件是tar文件时,会自动展开为一个目录并拷贝进新的镜像中;然而通过URL获取到的tar文件不会自动展开。复制或解压缩目录时,其行为与相同tar -x。

语法

ADD [--chown=<user>:<group>] <src>... <dest>
or
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (此格式对于包含空格的路径是必需的)

规则

  1. 该路径必须是内部语境的构建; 不能这样做ADD …/something /something,因为第一步 docker build是将上下文目录(和子目录)发送到docker守护程序。

  2. 如果是URL,并且不以斜杠结尾,则从URL下载文件并将其复制到。

  3. 如果是URL并以斜杠结尾,则从URL推断文件名,然后将文件下载到 /。例如,ADD http://example.com/foobar /将创建文件/foobar。该URL必须具有非平凡的路径,以便在这种情况下可以发现适当的文件名(http://example.com 将不起作用)。

  4. 如果是目录,则将复制目录的整个内容,包括文件系统元数据。

COPY

  • 复制宿主机上的文件到目标镜像中

语法

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (此格式对于包含空格的路径是必需的)

规则
ADD

ENTRYPOINT

  • 类似CMD指令的功能,用于为容器指定默认运行程序。
  • Dockerfile中可以存在多个ENTRYPOINT指令,但仅最后一个生效
  • CMD区别在于,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且这些命令行参数会被当做参数传递给ENTRYPOINT指令指定的程序。不过,docker run的--entrypoint选项的参数可覆盖ENTRYPOINT指定的默认程序

语法

ENTRYPOINT ["executable", "param1", "param2"] (执行表格,首选)
ENTRYPOINT command param1 param2 

VOLUME

  • 等同于docker run -v
  • 用于在镜像中创建一个挂载点目录。在dockerfile中只支持docker管理的卷,也就是说只能指定容器内的路径,不能指定宿主机的路径。宿主机可以通过 docker inspect container查看。

语法

VOLUME ["/data"]

注意事项

  • 基于Windows的容器上的卷:使用基于Windows的容器时,容器内的卷的目的地必须是以下之一:
    1. 不存在或空目录
    2. 除以下以外的驱动器 C:
  • 从Dockerfile内更改卷:如果在声明了卷后有任何构建步骤更改了卷内的数据,则这些更改将被丢弃。
  • JSON格式:列表被解析为JSON数组。必须用双引号(")而不是单引号(’)括住单词。
  • 主机目录是在容器运行时声明的:主机目录(挂载点)从本质上说是依赖于主机的。这是为了保留图像的可移植性,因为不能保证给定的主机目录在所有主机上都可用。因此,无法从Dockerfile内挂载主机目录。该VOLUME指令不支持指定host-dir 参数。创建或运行容器时,必须指定安装点。

WORKDIR

  • docker run -w
  • 指定工作目录,可以指多个,每个WORKDIR只影响他下面的指令,直到遇见下一个WORKDIR为止。
  • WORKDIR也可以调用由ENV指令定义的变量。

语法

WORKDIR /path/to/workdir
  1. 该WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则它将相对于上一条WORKDIR指令的路径

例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为/a/b/c

ARG

  • ARG命令同EVN类似,也是指定一个变量,但不同的是,ENV指令配合-e参数可以在docker run过程中传参,而使用ARG指令配合--build-arg参数可以在docker build过程中传参,这方便了我们为不同场景构建不同镜像。

语法

ARG <name>[=<default value>]

ONBUILD

  • 用于在Dockerfile中定义一个触发器。
  • ONBUILD后面指定的指令在docker build时是不会执行,构建完的镜像在被另一个Dockerfile文件中FROM指令所引用的时才会触发执行。

语法

ONBUILD [INSTRUCTION]

STOPSIGNAL

  • 指定发送使容器退出的系统调用信号。docker stop之所以能停止容器,就是发送了15的信号给容器内PID为1的进程。

语法

 STOPSIGNAL signal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值