Dockerfile 的使用

Dockerfile 的使用

Docker build命令和镜像构建过程

docker build命令使用的时候其参数有3种类型来表示构建context的3种来源:PATH, -URL更多>>

这里的构建context是指传入docker build命令的所有文件。
一般情况下,将本地主机的一个包含Dockerfile的目录中的所有内容作为context。context通过docker build命令传入到Docker daemon后,便开始按照Dockerfile中的内容构建镜像。

除了FROM指令,其它每一条指令都会在上一条指令所生成的镜像的基础上执行,执行完后会生成一个新的镜像层,新的镜像层覆盖在原来的镜像之上从而形成了新镜像。Dockerfile所生成的最终镜像就是在基础镜像上面叠加一层层的镜像层组建的

为了提高镜像构建的速度,Docker daemon会缓存构建过程中的中间镜像。当从一个已经在缓存中的基础镜像开始构建新镜像时,会像Dockerfile中的下一条指令和基础镜像的所有子镜像做比较,如果有一个子镜像是由相同命令生成的,则命中缓存,直接使用该镜像,而不用再生成一个新的镜像。

但是COPYADD命令与其它命令稍有不同,其他指令只对比生成镜像的指令字符串是否相同;COPYADD还要对比容器中的文件内容和所添加的文件内容是否相同。此外,镜像构建过程中,一旦缓存失效,则后续的指令都将生成新的镜像,而不再使用缓存。

Dockerfile指令

  • FROM

格式:

FROM <image>

FROM <image>:<tag>

FROM指令为后面的指令提供基础镜像,因些一个有效的Dockerfile必须以FROM作为第一条非注释指令。

  • ENV

格式:

ENV <key> <value>

ENV <key>=<value>

ENV用于声名明境变量。并且在Dockerfile中ENV指令声明环境可以被后面的特定指令(ENV,ADD,COPY,WORKDIR,EXPOSE,VOLUME,USER)解释使用。

使用格式:

$variable_name

${variable_name}
  • COPY

格式:

COPY <src> <dest>

<src>所指定的源可以有多个,但必须在context中,即必须是context根目录的相对路径。不能使用形如COPY ../something /something这样的指令。此外,<src>可以使用通配符指向所有匹配通配符的文件或目录,如,COPY hom* /mydir/

<dest>可以是文件或目录,但必须是目标镜像中的绝对路径或者相对于WORKDIR的相对路径。

  • ADD

格式:

ADD <src> <dest>

ADDCOPY在功能上很相似,但ADD还支持其他功能。<src>可以是一个指向一个网络文件的URL,此时若<dest>指向一个目录,则URL必须是完全路径,这样可以获得该网络文件名filename,该文件会被复制添加到<dest>/<filename>。例如,ADD http://example.com/foobar /会创建文件/foobar。

一般推荐使用COPY,因为COPY只支持本地文件,相比ADD而言,它更透明。

  • RUN

格式:

RUN <command>  // shell格式

RUN ["executable", "param1", "param2"] // exec格式,推荐格式

RUN指令会在前一条命令创建出的镜像的基础上创建一个容器,并在容器中运行命令,在命令结束运行后提交容器为新镜像。

当使用shell格式时,命令通过/bin/sh -c运行;
当使用exec格式时,命令是直接运行的,容器不调用shell程序,即容器中没有shell程序。exec格式中的参数会当成JSON数组被Docker解析,故必须使用双引号而不能使用单引号。因为exec格式不会在shell中执行,所以环境变量的参数不会被替换。

  • CMD

格式:

CMD <command> // shell格式
CMD ["executable", "param1", "param2"] // exec格式,推荐格式
CMD ["param1", "param2"] // 为ENTRYPOINT指令提供参数

CMD提供运行的默认值,默认值可以是一些参数,或指令。一个Dockerfile中只有最后一条CMD指令有效。而且CMD指令需要要ENTRYPOINT指令配合使用。

RUN指令不周的是:

RUN指令在构建镜像时执行命令,并生成的镜像;

CMD指令在构建镜像时并不执行任何命令,而是在容器启动时默认将CMD指令作为第一条执行的命令。如果用户在命令行界面运行docker run命令时指定了命令参数,则会覆盖CMD指令中的命令。

  • ENTRYPOINT

格式:

ENTRYPOINT <command> // shell格式

ENTRYPOINT ["executable", "param1", "param2"] // exec格式,推荐格式

ENTRYPOINT指令和CMD指令类似,都可以让容器在每次启动时执行相同的命令。但它们之间又有不同。一个Dockerfile中只有最后一条ENTRYPOINT指令有效。

当使用sheel格式时,ENTRYPOINT指令会忽略任何CMD指令和docker run命令的参数,并且运行在bin/sh -c中。这意味着ENTRYPOINT指令进程为bin/sh -c的子进程,进程在容器中的PID将不是1,且不能接受Unix信号。即当使用docker stop <container>命令时,命令进程接受不到SIGTERM信号。

我们推荐使用exec格式,使用此格式时,docker run传入的命令参数会覆盖CMD指令的内容,并且添加到ENTRYPOINT指令的参数中。

ENTRYPOINT的使用中可以看出,CMD可以是参数,也可以是指令,而ENTRYPOINT只能是命令;另外,docker run提供的运行命令参数可以覆盖CMD,但是不能覆盖ENTRYPOINT

Dockerfile 使用心得

  • 使用标签

给镜像打标签,易读的镜像标签可以帮助了解镜像的功能,如:

docker build -t "mydockerimage:1.0" .
  • 谨慎选择基础镜像

busybox < debian < centos < ubuntu

  • 充分利用缓存

为了有效地利用缓存,需要保证指令的连续性,尽量将所有Dockerfile文件中相同的部分都放在前面,而将不同的部分放在后面。

  • CMD和ENTRYPOINT

CMDENTRYPOINT指令指定了容器运行的命令,推荐二者结合使用。使用exec格式的ENTRYPOINT指令设置固定的默认命令和参数,然后使用CMD指令设置可变的参数。

  • 不要在Dockerfile中做端口映射

Docker的两个核心概念是可重复性可移植性,镜像应该可以在任何主机上运行多次。使用Dockerfile的EXPOSE指令,虽然可以将容器端口映射到主机端口上,但会破坏Docker的可移植性,且这样的镜像在一台主机上只能启动一个容器。所以端口映射就在docker run命令中用-p参数指定。

# 不要在Dockerfile中做如下映射
EXPOSE 80:8080

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

推荐阅读更多精彩内容

  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,418评论 15 147
  • 转载自 http://blog.opskumu.com/docker.html 一、Docker 简介 Docke...
    极客圈阅读 10,404评论 0 120
  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,669评论 1 21
  • 谢公天眷顾,貌质自峨巍。 才斗千层厚,文情百丈菲。 遂邀岩上月,又瞰雾中辉。 喜作逍遥客,云山带暮归。
    冰熙舍人阅读 431评论 8 13
  • 我的小喵你醒了吗 昨晚下了轰隆隆的雷雨 睡不着的时候 我想翻越所有的孤独去拥抱你 可你在我怀里却依旧怕 我想送你世...
    杜小萤阅读 289评论 0 1