Docker的Dockerfile

Dockerfile

配置容器化应用

• MariaDB:
• 命令行选项
• 配置文件
• 容器化方式运行MariaDB
• 启动容器
• exec -it
• 配置容器化应用
• docker run
• 通过自定义要运行的命令,并向传递命令行参数;
• 自定义镜像,将修改好的配置文件直接焙进镜像
• 环境变量
• docker run -e
• 存储卷


• 容器:一个进程;
• 进程终止,必将导致容器终止;
• 传递终止信号:SIGTERM,SIGKILL
• 进程没终止:running
• 健康状态检测
• 通过重启自愈

关于Dockerfile

•dockerfile只是构建docker映像的源代码
•Docker可以通过读取Dockerfile中的指令自动生成镜像
•dockerfile是一个文本文档,包含用户可以在命令行上调用的所有命令,以组合镜像
•使用Docker Build,用户可以创建一个自动生成,它连续执行多个命令行指令

Dockerfile格式

  • 格式
    • #注释
    • 指令参数
  • 指令不区分大小写
    • 然而,惯例是它们必须是大写,以便更容易将它们与论点区分开来
  • Docker按顺序在Dockerfile中运行指令
  • 第一条指令必须是“from”,以便指定要从中生成的基础图像

环境置换

•环境变量(用env语句声明)也可以在某些指令中用作dockerfile要解释的变量
•Dockerfile中也注明了环境变量使用variable_name或{variable_name}
{variable_name}语法还支持标准bash修饰符 •{variable:-word}表示如果设置了variable,则结果就是该值。如果未设置变量,则结果为word。
•${variable:+word}表示如果设置了变量,则结果将是word,否则结果是空字符串。

#NAME变量有值则显示原有值,没有值则显示tom
${NAME:-tom}
#NAME变量不为空则值为tom,否则值为空
${NAME:+tom}

.dockeringnore文件

•在docker cli将上下文发送给docker守护进程之前,它会在上下文的根目录中查找名为.dockerignore的文件
•如果该文件存在,cli将修改上下文以排除与其中模式匹配的文件和目录
•cli将.dockerignore文件解释为换行分隔的模式列表,类似于unix shell的文件glob

FROM

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

FROM <repository>[:<tag>]或 #使用名字是tag可省
FROM <resository>@<digest> #仓库中的镜像的hash码来进行拉取
<reposotiry>:制定作为base image的名称
<tag>:base image的标签,为可选项,省略时默认为latest

MAINTANIER (depreacted)

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

MAINTAINER <authtor's detail>
<author's detail>可是任何文本信息,但约定俗成地使用作者名称及邮件地址
MAINTAINER "magedu <mage@magedu.com>"
  • 示例:
#Description: test image
FROM nginx:latest
#基于父镜像构建其他docker镜像,父镜像:可以通过docker pull 命令获得,也可以自己制作
MAINTAINER cary.liu<xxx@126.com>
#Docker file维护者信息

LABEL

•label指令将元数据添加到镜像中
语法:label<key>=<value><key>=<value><key>=<value>…
label指令将元数据添加到镜像中。
标签是键值对。
要在标签值中包含空格,请使用引号和反斜杠,就像在命令行解析中一样。
一个镜像可以有多个标签。
可以在一行上指定多个标签。

  • 一个镜像可以有多个label。要指定多个labels[Docker推荐尽可能地把多个labels合并到一个LABEL指令中去。每一个LABEL指令会生成一个新的镜像层,如果你使用多个label,将导致构建出一个低效的镜像。这个示例只生成单个镜像层。
  • label是累积的,包括FROM镜像的lable。如果Docker遇到一个label/key已经存在,那么新的值将覆盖这个label/key。
    要查看一个镜像的label,使用docker inspect命令。
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"

#docker inspect 查看

"Labels": {
    "com.example.vendor": "ACME Incorporated"
    "com.example.label-with-value": "foo",
    "version": "1.0",
    "description": "This text illustrates that label-values can span multiple lines.",
    "multi.label1": "value1",
    "multi.label2": "value2",
    "other": "value3"
}

COPY

•用于从Docker主机复制文件至创建的新映像文件
• COPY <src> ... <dest> 或
• COPY ["<src>",... "<dest>"]
• <src>:要复制的源文件或目录,支持使用通配符
• <dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定则以WORKDIR为其起始路径;
• 注意:在路径中有空白字符时,通常使用第二种格式
•文件复制准则
• <src>必须是build上下文中的路径,不能是其父目录中的文件
• 如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制
• 如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾
• 如果<dest>事先不存在,它将会被自动创建,这包括其父目录路径

COPY yum.repos.d  /etc/yum.repos.d/
[root@localhost img1]# ls
Dockerfile  index.html
[root@localhost img1]# cat index.html
test
[root@localhost img1]# cat Dockerfile 
#Description: test image
FROM nginx:latest
MAINTAINER "wsl <wsl@qq.com>"
COPY index.html /data/web/www/html/

[root@localhost img1]# docker build -t mynginx:test ./
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM nginx:latest
 ---> 5a3221f0137b
Step 2/3 : MAINTAINER "wsl <wsl@qq.com>"
 ---> Running in 3c1a4872fc92
Removing intermediate container 3c1a4872fc92
 ---> df22d9badea1
Step 3/3 : COPY index.html /data/web/www/html/
 ---> 2c69f2815bcc
Successfully built 2c69f2815bcc
Successfully tagged mynginx:test
[root@localhost img1]# docker run  --name test1  --rm mynginx:test cat /data/web/www/html/index.html
test

ADD

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

ADD  http://nginx.org/download/nginx-10.1.0.tar.gz  (只会下载,不会解压)
WORKDIR /usr/local/src/
ADD nginx-0.1.0.tar.gz ./ (会自动解压成目录,nginx-0.1.0.tar.gz为宿主机文件)

VOLUME

• 用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其它容器上的 卷
• VOLUME <mountpoint> 或
• VOLUME ["<mountpoint>"]
• 如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中

VOLUME /data/mysql/ (只能指定docker卷,不能指定宿主机)

ENV

• 用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令 (如ENV、ADD、COPY等)所调用
• 调用格式为variable_name或{variable_name}
• ENV <key> <value> 或
• ENV <key>=<value> ...
• 第一种格式中,<key>之后的所有内容均会被视作其<value>的组成部分,因此,一次只能设置一个变量;
• 第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果 <value>中包含空格,可以以反斜线()进行转义,也可通过对<value>加引号进行标识;另 外,反斜线也可用于续行;
• 定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能

ENV DOC_ROOT=/data/web/  \
         WEB_SERVER_PACKGE="nginx-1.15.2"

COPY index.html ${DOC_ROOT:-/data/web/}  (:-设置默认值)
WORKDIR /usr/local/
ADD ${WEB_SERVER_PACKGE}.tar.ge ./src/

# 根据-e 改变之前的变量
[root@localhost ~]# docker run -itd -e DOC_ROOT="test" --name mynginx -P  mynginx:latest

RUN

• 用于指定docker build过程中运行的程序,其可以是任何命令
• RUN <command> 或
• RUN ["<executable>", "<param1>", "<param2>"]
• 第一种格式中,<command>通常是一个shell命令,且以“/bin/sh -c”来运行它,这意味着此进程 在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器 时,此进程接收不到SIGTERM信号;
• 第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的 <paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起 ,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令 依赖于此shell特性的话,可以将其替换为类似下面的格式。
• RUN ["/bin/sh", "-c", "<executable>", "<param1>"] • 注意:json数组中,要使用双引号

RUN cd /usr/local/src/ &&  \
         rm -rf ./*

CMD

• 类似于RUN指令,CMD指令也可用于运行任何命令或应用程序,不过,二者 的运行时间点不同
• RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像 文件启动一个容器时
• CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也 将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
• 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
• CMD <command> 或
• CMD [“<executable>”, “<param1>”, “<param2>”] 或 • CMD ["<param1>","<param2>"]
• 前两种语法格式的意义同RUN
• 第三种则用于为ENTRYPOINT指令提供默认参数

CMD ["/bin/httpd","-f","-h","/data/web/html/"]
CMD /bin/httpd   -f  -h  /data/web/html/

ENTRYPOINT

• 类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个 单独的可执行程序
• 与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的 参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定 指定的程序
• 不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
• ENTRYPOINT <command>
• ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
• docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到 ENTRYPOINT命令最后做为其参数使用
• Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

ENTRYPOINT /bin/httpd   -f  -h  /data/web/html/

#docker run --name mynginx -it --rm -P mynginx:latest ls /data/web/html
#上述启动方式相当于默认启动程序为 /bin/httpd   -f  -h  /data/web/html/ ls /data/web/html
#docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到
ENTRYPOINT命令最后做为其参数使用说得就是上面这个意思
# --entrypoint string              Overwrite the default ENTRYPOINT of the image

CMD ["/bin/httpd","-f","-h","/data/web/html/"]
ENTRYPOINT ["bin/sh","-c"]
#docker run --name mynginx -it --rm -P mynginx:latest "ls /data/web/html"
#此时会覆盖掉CMD的参数,除非使用--entrypoint

示例:

FROM nginx:1.14
LABEL maintainer="wsl <wsl@qq.com>"

ENV NGX_DOC_ROOT='/data/web/html/'

ADD index.html ${NGX_DOC_ROOT}
ADD entrypoint.sh /bin/

CMD ["usr/sbin/nginx","-g","daemon off;"]

ENTRYPOINT ["/bin/entrypoint.sh"]

#############################
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf << EOF
server {
            server_name ${HOSTNAME};
            listen ${IP:-0.0.0.0}:${PORT:-80};
            root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF

exec "$@"  #(将参数覆盖当前进程作为一个第一进程启动)

###############

docker run --name mynginx  -e "PORT=8080" -it --rm -P mynginx:latest 

#可以将PORT作为环境变量传入,并作用在nginx配置文件中

USER

• 用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT 指令指定的程序时的用户名或UID
• 默认情况下,container的运行身份为root用户
• USER <UID>|<UserName>
• 需要注意的是,<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效 UID,否则,docker run命令将运行失败

USER nginx

HEALTHCHECK

• healthcheck指令告诉docker如何测试容器以检查它是否仍在工作。
• 这可以检测到一些情况,例如web服务器陷入无限循环,无法处理新连接,即使服务器进程仍在运行。
• 健康检查指令有两种形式:
• HEALTHCHECK [OPTIONS] CMD命令(通过在容器内运行命令检查容器运行状况)
• HEALTHCHECK NONE(禁用从基本映像继承的任何healthcheck)

HEALTHCHECK 健康监测
--interval=DURATION(defailt:30s) 默认30秒监测一次,参数可以是5m
--timeout=DURATION(defailt:30s) 默认30秒超时
--start-period=DURATION(defailt:0s) 默认运行0秒后开始监测
--retries=N(defailt:3) 默认失败3次
响应值:
0表示健康
1表示不健康
2表示预留的没什么意义

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

ARG

• ARG指令定义了一个变量,用户可以通过使用-BuildAdgBuild命令使用BuildARGE.VARNAMEX==Value>标志,在生成时传递给生成器。
• 如果用户指定在DOCKFILE文件中未定义的生成参数,则生成将发出警告。
• 语法:arg<name>[=<default value>]
• dockerfile可以包含一个或多个arg指令。
• ARG指令可以可选地包括默认值:
• arg版本=1.14
• arg用户=magedu

ARG author="wsl <wsl@qq.com>"
LABEL maintainer = ${author}

docker build --build-arg author="yhf <yhf@qq.com>"

SHELL

• shell指令允许重写用于命令的shell形式的默认shell。
• Linux上的默认shell为[“/bin/sh”、“-c”],Windows上的默认shell为[“cmd”、“/s”、“/c”]。
• shell指令必须以json格式写入dockerfile中。
• 语法:shell[“executable”,“parameters”]
• shell指令可以多次出现。
• 每一条shell指令都会覆盖所有先前的shell指令,并影响所有后续指令。

STOPSIGNAL

• stopsignal指令设置将发送到容器以退出的系统调用信号。
• 这个信号可以是一个有效的无符号数,它匹配内核的SysCurl表中的一个位置,例如9,或者格式签名中的一• 个信号名,例如SIGKEY。
• 语法:STOPSIGNAL signal

ONBUILD

• 用于在Dockerfile中定义一个触发器
• Dockerfile用于build映像文件,此映像文件亦可作为base image被另一个Dockerfile 用作FROM指令的参数,并以之构建新的映像文件
• 在后面的这个Dockerfile中的FROM指令在build过程中被执行时,将会“触发”创 建其base image的Dockerfile文件中的ONBUILD指令定义的触发器
• 语法
• ONBUILD <INSTRUCTION>
• 尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和 MAINTAINER指令
• 使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuild
• 在ONBUILD指令中使用ADD或COPY指令应该格外小心,因为新构建过程的上下文在缺少指 定的源文件时会失败
• 在别人基于你的镜像做镜像时会触发

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

推荐阅读更多精彩内容