Docker笔记:Dockerfile指令

Docker可以通过Dockerfile的指令来自动构建镜像。Dockerfile是一种文本文件,用户可以通过Dockerfile来创建一个自动化的构建。

指令语法

本篇主要介绍和说明Dockefile中的指令语法。

FROM

用法:
FROM <image>[:<tag>] [AS <name>]
FROM <image>[@<digest>] [AS <name>]
说明:

FROM指令用于初始化新的构建阶段并未后续指令设置基本镜像。因此,Dockerfile必须以FROM指令开始。

备注:
  • ARG指令允许在Dockerfile定义变量,是唯一优于From执行的指令。
  • FROM可以在单个Dockerfile中多次出现以创建多个镜像,或者作为另一个构建阶段的依赖项。
  • As <name>为可选项,相当于为该镜像取一个别名。
  • [:<tag>][@<digest>]为可选项,如果不指定则使用默认的latest标签。

RUN

用法:
# shell form
RUN <command>
# exec form
RUN ["executable", "param1", "param2"]
说明:

RUN指令用于在当前镜像上执行指定命令,每运行一条RUN指令,镜像添加新的一层并提交。

备注:
  • shell form将在shell终端中运行命令,即/bin/sh -c;exec form则使用exec执行。如果需要指定其它终端则可以通过exec form实现,例如:
RUN ["/bin/bash", "-c", "echo hello"]
  • shell form中,针对较长的命令可以通过\进行换行。例如:
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
  • exec form中,参数必须使用双引号",而非单引号'。如果参数带有\需要对其进行转义,例如:
RUN ["c:\\windows\\system32\\tasklist.exe"]
  • exec form中如果不指定executable将不会调用shell命令,即正常的shell进程将不会生成。
# 实际执行会获取不到$HOME
RUN [ "echo", "$HOME" ]
# 可以在exec form中指定executable
RUN [ "sh", "-c", "echo $HOME" ]

CMD

用法:
# exec form,推荐方式
CMD ["executable","param1","param2"]
# 提供给ENTRYPOINT的默认参数
CMD ["param1","param2"]
# shell form
CMD command param1 param2
说明:

CMD指令的主要目的是为了给启动容器提供默认命令项。在Dockerfile中只能有一个CMD指令。如果有多个CMD,只有最后一条会生效。

备注:
  • 如果用户启动容器时指定了CMD指令,则会覆盖Dockerfile中指定的CMD命令。

LABEL

用法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
说明:

LABEL指令会将元数据添加到镜像,格式为键值对。如果键值中包含空格,需使用引号",换行则使用反斜杠\

备注:
  • 一个镜像可以有多个Lable,如果一个Label已经存在具有不同的值,则最近应用的值将覆盖先前设置的值。

MAINTAINER (弃用)

用法:
MAINTAINER <name>
说明:

MAINTAINER指令用于描述镜像的维护者信息。

备注:
  • 官方文档以将其标注为deprecated,并建议使用更为灵活的LABEL指令。

EXPOSE

用法:
EXPOSE <port> [<port>/<protocol>...]
说明:

EXPOSE指令通知Docker容器运行时监听的网络端口。可以指定监听端口的协议,默认为TCP。

备注:

EXPOSE指令不会做端口映射,实际在docker run并指定-p-P时生效。

ENV

用法:
# 单个设置
ENV <key> <value>
# 允许一行设置多个
ENV <key>=<value> ...
说明:

ENV指令用于设置容器的环境变量。指定的环境变量会被后续RUN指令使用,并在容器运行时保持。

ADD

用法:
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
说明:

ADD指令用于复制指定的<src>到容器中<dest><src>可以是文件、目录或远程文件URL。

备注:
  • --chown仅支持构建Linux容器,并不适用于构建Windows容器。
  • ADD遵守以下规则:
    • <src>路径必须在构建上下文中,所以无法加入以下命令:
    # 在执行docker build时获取了Dockerfile的上下文路径和子目录
    # 上层目录则获取不到,所以这种写法是错误的
    ADD ../something /something
    
    • 如果<src>是URL且<dest>不以/结尾,则从URL下载文件并复制到<dest>
    • 如果<src>是URL且<dest>/结尾,则从URL推断文件名并将文件下载到<dest>/<filename>。例如:
    # 将创建/foobar
    ADD http://example.com/foobar /
    
    • 如果<src>是一个本地压缩文档,则将其解压为目录,远程资源则不会解压。
    • 如果<src>是一个目录,会复制整个目录的内容,包括文件系统的元数据。目录不会复制,仅复制目录下的内容。
    • 如果<src>是其它类型文件,则将其与元数据一起复制。在这种情况下,如果<dest>/结尾,则将其视为目录,<src>的内容将写入<src>/base(<src>)。反之若不以/结尾,则视为常规文件,<src>内容将写入<dest>
    • 如果<dest>不存在,则会创建。

COPY

用法:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
说明:

COPY指令用于复制本地主机的<src>到容器中的<dest>

备注:
  • ADD功能类似的一个指令,主要差别在于仅支持本地文件复制并且不会对压缩文件进行解压。
  • 当使用本地目录为<src>时,推荐使用COPY指令。

ENTRYPOINT

用法:
# exec form
ENTRYPOINT ["executable", "param1", "param2"]
# shell form
ENTRYPOINT command param1 param2
说明:

ENTRYPOINT指令用于配置容器启动后执行的命令。

备注:
  • 只能有一个ENTRYPOINT指令。如果有多个,只有最后一条会生效。
  • 通过docker run --entrypoint命令对ENTRYPOINT指令进行覆盖。
  • docker run <image>后的命令行参数会追加到exec formENTRYPOINT后面,并覆盖使用CMD指定的所有参数。

VOLUME

用法:
VOLUME ["/data"]
说明:

VOLUME指令创建一个可以从本地或其他容器挂载的挂载点,一般存放需要持久化的数据。

备注:
  • ["/data"]可以是个JSON array,即支持以下格式:
VOLUME ["/var/log/"]
VOLUME /var/log 
VOLUME /var/log /var/db

USER

用法:
USER <user>[:<group>]
USER <UID>[:<GID>]
说明:

USER指令设置启动容器的用户或UID,用户组或GID(可选)。

备注:
  • 如果设置了用户,那么后续的RUNCMDENTRYPOINT指令也会使用指定用户。

WORKDIR

用法:
WORKDIR /path/to/workdir
说明:

WORKDIR指令用于为后续的RUNCMDENTRYPOINT指令设置工作目录。

备注:
  • 如果指定的工作目录不存在,即使未在后续的命令中使用,WORKDIR指令仍会创建。

ARG

用法:
ARG <name>[=<default value>]
说明:

ARG指令用于设置变量。在docker build创建镜像的时候,使用--build-arg <varname>=<value>来指定参数。

备注:
  • 如果用户指定了变量参数,但未在Dockerfile中定义,则会给出一个warning:
[Warning] One or more build-args [foo] were not consumed.
  • 如果ARG指令设置了默认值,那么当构建镜像时没有指定参数,则使用这个默认值。

ONBUILD

用法:
ONBUILD [INSTRUCTION]
说明:

ONBUILD指令用于设置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。换言之,当这个镜像创建完成后,如果有其他镜像以这个镜像为基础,会先执行这个镜像的ONBUILD指令。

备注:
  • ONBUILD ONBUILD这种写法是不被允许的。
  • ONBUILD指令可能不会触发FROMMAINTAINER指令。

STOPSIGNAL

用法:
STOPSIGNAL signal
说明:

STOPSIGNAL指令用于设置容器退出时给系统发送的信号。

HEALTHCHECK

用法:
# 在容器内部执行一个命令进行健康检查
HEALTHCHECK [OPTIONS] CMD command
# 取消继承镜像的健康检查
HEALTHCHECK NONE
说明:

HEALTHCHECK指令用于容器监控检查。

备注:
  • [options]选项如下:
    • --interval=DURATION (default: 30s)
    • --timeout=DURATION (default: 30s)
    • --start-period=DURATION (default: 0s)
    • --retries=N (default: 3)
  • 执行命令的退出码表明了容器的健康状态,具体如下:
    • 0: success - 容器健康且可用
    • 1: unhealthy - 容器已经不在正常工作了
    • 2: reserved - 保留值

SHELL

用法:
SHELL ["executable", "parameters"]
说明:

SHELL指令允许覆盖shell form命令的默认shell。

备注:
  • SHELL指令会影响后续的RUNCMDENTRYPOINT指令。
  • SHELL指令是Docker 1.12加入的新功能。

写在后面

  • 本篇主要参考了docker的官方文档,对其进行了整理,便于查阅。由于个人水平有限,可能存在理解不到位或者错误的地方,欢迎指正。
  • 本篇基于当前最新Docker版本v18.03,有些指令没有特别展开说明和备注,详细信息可以参考官方文档,地址如下:
    docker官方文档
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,494评论 0 120
  • 一、Docker创建镜像的方式有两种: 一种通过commit的方式:把做了一系列操作的容器关闭,然后利用docke...
    jie0112阅读 3,827评论 0 3
  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,367评论 1 39
  • 听说荒地植草十年,可换一时春生。 但是,可能只是刚好喜欢田野,而我却一直愚笨而已~ ​​​
    Alice喜欢不二的玫瑰阅读 170评论 0 0
  • 彭老太太八十三岁了,于腊月初一夜驾鹤瑶池。 七儿两女,孙子,外甥,重孙子,几十人的大家庭,这老太太仙逝,出殡的日子...
    虹树阅读 2,445评论 21 22