Dockerfile构建镜像

一,简单介绍

docker镜像构建方式有两种方式,第一种是启动基础容器之后,进入容器安装所需要的文件,配置,变量等,完成后使用docker commit提交成为一个新的镜像,第二种则是通过编写dockerfile文件,进行镜像制作,使用docker build命令进行镜像的构建。第一种方式可以看到镜像的生成过程,但是不便于自动化;第二种方式则比较直观,可以结合devops实现自动打包发布,本文则介绍如何利用dockerfile实现docker镜像的制作。

Dockerfile描述了组装镜像的步骤,其中每条指令都是单独执行的。除了FROM指令之外,其他每一条指令都会在上一条指令生成的镜像上执行并生成一个新的镜像层。Dockerfile生成的最终镜像就是在基础镜像上一层一层叠加组建而成的。同时,为了提高镜像构建的速度,Docker会缓存构建过程中的中间镜像。当从一个已在缓存中的基础镜像开始构建新镜像时,会将dockerfile中的下一条指令和基础镜像的所有子镜像做比较,如果有一个子镜像是由相同的指令生成的,则命中缓存,直接使用该镜像。这里我们需要注意一点,镜像制作过程中缓存命中与否检查的是dockerfile中的指令,并不会检查镜像是否一致;当然COPY,ADD两个指令例外,不仅检测会指令字符集,还会检测对比需要添加的文件是否一致(校验不考虑修改访问时间,考虑元数据以及内容)。如我们在镜像中使用了

RUN apt-get -y upgrade

指令,docker daemon在校验的时候,会判断指令集相同,从而使用缓存并不会更新。解决这个问题可以使用下列方法,人为的造成指令字符集不一致

RUN apt-get update && apt-get install -y \
    aufs-tools \
    automake \    
    build-essential \
 && rm -rf /var/lib/apt/lists/*

另外一种方法就是在docker build时添加参数 --no-cache=true


二,典型结构

#第一部分  指明基础镜像
#FROM registry:5000/centos_ssh:1.0.0
FROM registry:5000/centos:7.3.1611

##第二部分  维护者信息
MAINTAINER liyang liyang@pand-auto.com

## 第三部分  镜像操作指令  

#更改时区
RUN echo "Asia/Shanghai" > /etc/timezone

# 设置环境变量
#ENV CATALINA_HOME /usr/local/tomcat
ENV JAVA_HOME  /usr/local/jdk1.8.0_161
ENV PATH $PATH:$JAVA_HOME/bin
#ENV PATH $PATH:$CATALINA_HOME/bin

#创建日志目录
RUN mkdir -p /www/logs/applogs 

#拷贝host文件至容器中,以便后续直接添加至容器host文件中
COPY hosts /myhosts
#拷贝tomcat和jdk文件到容器中

COPY tomcat /usr/local/
COPY jdk1.8.0_161 /usr/local/jdk1.8.0_161

#拷贝启动脚本至容器中

COPY run.sh /run.sh
RUN chmod +x /run.sh

#拷贝后台项目至容器中
COPY VRBP_Admin_war_exploded /tomcat/webapps/Admin

EXPOSE 8080 

## 第四部分 容器启动时执行的命令

CMD [ "/run.sh" ]

run.sh内容如下:

#!/bin/bash
cat /myhosts >>/etc/hosts
${CATALINA_HOME}/bin/catalina.sh run

注:因为每次启动容器的时候hosts文件都会重新生成,所以本文中镜像采用启动后执行命令将hosts内容追加至/etc/hosts文件中的方法


三,常用指令说明

FROM

格式: FROM <image> 或者 FROM <image>:<tag>

FROM指令的功能是为后面的指令提供基础镜像,所以该指令一定是Dockerfile的第一个非注释指令。如果FROM指令中没有指明tag,则默认为latest

MAINTAINER

格式:MAINTAINER <information of maintaier>

MAINTAINER指明镜像维护者的信息,通常是dockerfile的第二个非注释指令

ENV

格式:ENV <key> <value> 或者 ENV <key>=<value> ...

ENV指令为镜像创建出来的容器声明环境变量,并且可以在dockerfile被特定指令使用(ADD,COPY,EXPOSE,WORKDIR等)

需要注意一点的是,定义容器中的变量的时候尽量不要使用/etc/profile文件,直接使用ENV定义。因为该配置文件只有在交互式启动shell时候才会读取,而docker run使

用的是/bin/bash -c,非交互式模式,所以直接写入/etc/profile的环境变量不能直接生效,需要source一遍配置文件,推荐使用ENV直接定义固化。

RUN

格式:RUN <command> 或者 RUN ["executable","param1","param2"]

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

RUN指令两种运行方式可以理解为shell以及exec格式,当使用shell格式时,命令通过调用/bin/sh -c运行;使用exec格式时,命令直接运行,容易不调用shell,exec格式

格式中的参数会被当做JSON被docker解析,exec不会在shell中执行,所以环境变量的参数不会被替换。

COPY/ADD

格式:ADD/COPY <src> <dest>

COPY,ADD指令都可以拷贝本地文件或者目录到新的镜像中,其中ADD命令还支持URL并且可以在自动解压tar包。如果原路径是一个目录,则只会拷贝目录中的内容,不

会在镜像中创建该目录;源路径是相对于执行build的相对路径;目标路径不存在时会自动创建;

CMD

格式:有下列三种

CMD   <command>

CMD   ["executable","Param1","param2"]

CMD   ["Param1","param2"]   为ENTRYPOINT传递参数

CMD指令提供容器启动时运行的默认值,可以为参数,命令。当一个dockerfile文件中存在多个CMD指令时,只有最后一个CMD生效。CMD指令在镜像构建时不运行任何命

令,而是在容器启动时默认将CMD指令作为第一条执行的命令,如果用户在docker run命令中指定了命令参数则会覆盖CMD指令中的命令

ENTRYPOINT

格式:

ENTRYPOINT   <command>

ENTRYPOINT   ["executable","Param1","param2"]

ENTRYPOINT指令与CMD指令类似,不同点在于ENTRYPOINT不会被docker run中的命令参数覆盖
EXPOSE

格式:EXPOSE [...]

定义容器向外暴露的窗口,不建议在此处定义端口映射


四,镜像构建

命令:docker build -t <image>:<tag> .

上述命令中最后有一个点,表示dockerfile所在的目录,也可以直接写为绝对路径(不推荐),该命令会自动去寻找目录下的Dockerfile文件并读取其内容。也可以使用 -f指明dockerfile文件路径。

注意:

1.固定内容尽量写在dockerfile前列,充分利用缓存
2.RUN指令的命令结合管道可以减少镜像层数
3.CMD和ENTRYPOINT可以结合使用
4.如果是本地文件尽量使用COPY

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