Dockerfile

dockerfile指令

FROM

from 指令是最重要的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为进项文件构建过程指定基础镜像,后续的指令运行与此基准镜像所提供的运行环境
实践中基准镜像可以是任何可用镜像文件,默认情况下docker bulid会在docker主机上查找指定的镜像文件,在其不存在时,则会从dockerHub Registry上去拉去,如果找不到指定的镜像文件,docker bulid会返回一个错误信息

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

FROM busybox:$VERSION

MAINTAINER

用于让Dockerfile制作者提供本人详细信息,dockerfile并不限制MAINTAINER指令可出现在什么位置,但是推荐将其放置于FROM指令之后

语法:
MAINTAINER <name>

COPY

用于用docker主机复制文件至创建的新镜像文件

语法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] 
<src>: 要复制的源文件或者目录,支持使用通配符
<dest>: 目标路径,正在创建的image的文件系统路径,建议<dest>使用绝对路径否则copy指定则以workdir为起始路径
注意:
<src>必须是bulid上下文中的路径不能是其父目录的中的文件
如果<src>是目录,则其内部的文件或者是其子目录都会被递归复制,单<src>自身目录则不会被复制
如果制定了多个<src>,或者,<src>中使用了通配符,则<dest>必须是一个目录,必须一/结尾
如果<dest>事先不存在,它会被自动创建,这包括其父目录路径

文件:
COPY index.html /data/web/html/
目录:
COPY yum.repos.d /etc/yum.repos.d/

ADD

ADD指令类似于COPY指令,但是ADD指令支持使用TAR文件和URL路径

语法:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
同COPY指令
如果<src>为URL切<dest>不以/结尾,则<src>指定的文件将被下载并直接创建<dest>,如果<dest>以/结尾则文件名URL指定的文件将被下载并保存为<dest><filename>
如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于"tar -xf ",然而通过URL获取到的tar文件将不会自动展开
如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径,如果<dest>不以/结尾,则其被视作为一个普通文件,<src>的内容将会被直接写到<dest>

URL下载的tar文件解压:
ADD http://nginx.org/download/nginx-1.18.0.tar.gz  /usr/local/src/
本地系统tar解压:
ADD nginx-1.18.0.tar.gz  /usr/local/src/

WORKDIR

用于为Dockerfile中所有的RUN,CMD,ENTRYPOINT,COPY和ADD指定设定工作目录

WORKDIR /path/to/workdir
在Dockerfile文件中WORKDIR指令可出现多次,其路径也可以为相对路径,不过其是相对于此前一个WORKDIR指令的路径
另外WORKDIR也可以调用ENV指定定义的变量
例子:
  WORLDIR $STATEPATH

WORKDIR /usr/local/
ADD nginx-1.18.0.tar.gz ./src

VOLUME

用于在image中创建一个挂载点目录,已挂在docker host 上的卷或者其他容器上的卷

语法:
VOLUME ["/data"]
VOLUME /data
如果挂载点目录路径下此前文件名存在,在docker run命令会在挂载卷完成后将此前的所有文件复制到新挂载卷中

EXPOSE

用于为容器打开指定的要坚挺的端口已实现外部通信

语法:
EXPOSE <port> [<port>/<protocol>...]
<portocol> 用于指定传输层协议,可为tcp或者udp,默认为TCP协议
EXPOSE指令一次可指定多个端口
例:
EXPOSE 11234/udp 11234/tcp

EXPOSE 80

ENV

用于为镜像定义所需要的环境变量,并可被Dockerfile文件中位于其后的其他指令(如ENV,ADD,COPY等)所调用
调用格式:
$variable_name或者$(variable_name)

语法:
ENV <key> <value>
ENV <key>=<value> ...
第一种格式中,<key>之后的所有内容均会被视作其<value>的组成部分,因此一次只能设置一个变量
第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果value中包含空格,可以以反斜线(\)进项转义,也可以通过对value加引号进行标识,另外反斜线也可用于续航
定义多个变量时建议是建议使用第二种方式,以便在同一层中完成所有功能

ENV DOCS_ROOT /data/web/html/
COPY index.html $DOCS_ROOT
或
ENV DOCS_ROOT=/data/web/html/ \    WEB_SERVER_PACKAGE="nginx-1.18.0"
COPY index.html ${DOCS_ROOT}
ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src

RUN

用于定义docker build过程中运行的程序,其可使任何命令
语法:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)
第一个格式<command>通常是一个shell命令,且以"/bin/sh -c"来运行它,这意味着此进程在容器中的PID不为1,不能接受uinx信号,因此当时用docker stop <container>停止容器时此进程接收不到SIGTERM信号
第二种语法格式中的参数是一个json格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或者参数,然而此种选项的命不会以"/bin/sh -c"来发起,因此常见的shell操作如变量替换以及通配符替换将不会进行,不过要运行的命令依赖于此shell特性的话可以将其替换为类似一下格式,
RUN ["/bin/bash", "-c", "executable","param1"]

CMD

类似于RUN指令,CMD指令也可以用于运行任何命令或应用程序,不过二者的运行时间点不同
RUN指令运行于镜像文件构建过程中,而CMD指令运行基于Dockerfile构建出的新镜像文件启动一个容器时
CMD指令的首要目的在于为启动容器指定默认要运行的程序,且其运行结束后,容器也将终止,不过CMD指令的命令起可以被docker run的命令选项进行覆盖
在Dockerfile中可以存在多个CMD指令,但尽最后一个生效

语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
前两种语法格式同RUN
第三种则用于为ENTRYPOINT指令提供默认参数

情况一:
Dockerfile中定义:
FROM busybox
MAINTAINER "xiaofang"
ENV WEB_DOCS_ROOT="/data/web/html/"

RUN mkdir -p ${WEB_DOCS_ROOT} && \
    echo 'hello world' > ${WEB_DOCS_ROOT}/index.html

CMD /bin/httpd -f -h ${WEB_DOCS_ROOT}

使用以上这这种方式会以shell子进程方式运行
使用docker inspect httpd:v1.1查看镜像的CMD详细:
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/sh\" \"-c\" \"/bin/httpd -f -h ${WEB_DOCS_ROOT}\"]"
            ],

情况二:
FROM busybox
MAINTAINER "xiaofang"
ENV WEB_DOCS_ROOT="/data/web/html/"

RUN mkdir -p ${WEB_DOCS_ROOT} && \
    echo 'hello world' > ${WEB_DOCS_ROOT}/index.html

CMD ["/bin/httpd","-f","-h ${WEB_DOCS_ROOT}"]

使用json数组的方式定义是不会以shell子进程的方式运行,通常这这种情况我们会以“/bin/sh -c”的方式进行运行

 "Cmd": [
                "/bin/httpd",
                "-f",
                "-h ${WEB_DOCS_ROOT}"

ENTRYPOINT

类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且这些命令行参数会被当做参数传递给ENTRYPOINT指定的程序
不过docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令的指定的程序

语法:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅最后一个会生效


ENTRYPOINT /bin/httpd -f -h /data/web/html/
如果同时定义了CMD和ENTRYPOINT,CMD会被当做参数传给ENTRYPOINT 

USER

用于指定运行image时的或运行dockerfile中任何RUN,CMD或,ENTRYPOINT指令的程序用户名或UID
默认情况下container的运行身份为root用户

语法:
USER <user>[:<group>]
or

USER <UID>[:<GID>]

需要注意的是<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户有效的UID否则docker run命令运行失败

HEALTHCHECK

HEALTHCHECK指令告诉 Docker 如何测试容器以检查它是否仍在工作。这可以检测诸如 Web 服务器陷入无限循环并且无法处理新连接的情况,即使服务器进程仍在运行。
当容器指定了健康检查时,除了其正常状态之外,它还具有健康状态。此状态最初为starting。每当健康检查通过时,它就会变成healthy(无论它之前处于什么状态)。连续失败一定次数后,变为unhealthy。

之前可以出现的选项CMD有:
--interval=DURATION(默认值:30s)
--timeout=DURATION(默认值:30s)
--start-period=DURATION(默认值:0s)
--retries=N(默认值:3)

运行状况检查将在容器启动后首先运行interval秒,然后在每次之前的检查完成后再次运行interval秒。
如果检查的单次运行时间超过timeout秒,则认为检查失败。
它需要重试连续的健康检查失败才能考虑容器unhealthy。
start period为需要时间引导的容器提供初始化时间。在此期间的探测失败将不计入最大重试次数。但是,如果在启动期间健康检查成功,则认为容器已启动,所有连续失败都将计入最大重试次数。

HEALTHCHECK一个 Dockerfile 中只能有一条指令。如果您列出多个,则只有最后一个HEALTHCHECK才会生效。

命令的退出状态指示容器的健康状态。可能的值为:

0:成功 - 容器运行良好,可以使用
1:不健康 - 容器不能正常工作
2:reserved - 不要使用这个退出代码

语法:
HEALTHCHECK [OPTIONS] CMD command (通过在容器内运行命令来检查容器健康状况)
HEALTHCHECK NONE (禁用从基础镜像继承的任何健康检查)

例:
HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

SHELL

该SHELL指令允许覆盖用于命令的shell形式的默认 shell 。Linux 上的默认 shell 是["/bin/sh", "-c"],Windows 上是["cmd", "/S", "/C"]. 该SHELL指令必须以 JSON 格式写入 Dockerfile。

该SHELL指令在 Windows 上特别有用,因为 Windows 有两种常用且截然不同的本机 shell:cmd和powershell,以及可用的备用 shell,包括sh.

语法:
 SHELL ["executable", "parameters"]


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容