Dockerfile是一个用于构建Docker镜像的文本文件,其中包含了创建Docker镜像的全部指令。基于这些指令,可以使用”docker  build”命令来创建镜像。

一:用法

”docker  build”命令通过Dockerfile,以及一个上下文环境来构建镜像。所谓构建上下文,是指本地目录中的所有文件。比如使用当前目录作为上下文来构建镜像:

$ docker build .

构建流程中,第一件事就是将上下文中的所有文件上传给Docker deamon。因此,一般情况下,上下文的目录中应该只包含Dockerfile,以及其他必要的文件。

一般情况下,Dockerfile的文件名就是”Dockerfile”,并位于上下文的根目录下。不过可以通过”-f”选项指定其他其他文件作为Dockerfile,比如:

$ docker build -f /path/to/a/Dockerfile .

可以通过”-t”选项,指明要创建的镜像名以及tag,比如:

$ docker build -t shykes/myapp:1.0.2 .

Docker daemon逐条执行Dockerfile中的指令,并将指令执行结果提交为中间镜像。注意,每条指令都是独立运行,因此向”RUN  cd /tmp”这样的指令,对于后续的指令没有任何效果。

为了加快”docker  build”的执行速度,Docker会尽可能的重用中间镜像,也就是所谓的缓存。

Docker在执行每条指令时,都会检查缓存中是否有可重用的镜像,若有则直接使用该镜像,而无需创建新的重复镜像。检查镜像是否可重用的基本规则如下:

1:若父镜像已经处于缓存中,则会将下一条指令与该父镜像的所有子镜像进行对比,查看这些子镜像是否是使用相同指令构建的,若是,则可以使用该子镜像。

2:一般情况下,仅将Dockerfile中的指令与子镜像进行比对就足够了。不过还有其他一些指令需要额外的检查。

比如像ADD和COPY指令,除了对比指令之外,还会检查镜像中的文件内容。对于这两条指令,会检查相应文件的内容,计算其校验码,并与镜像中相应文件的校验码进行匹配。因此,如果文件内容发生了变化,则该子镜像也不再可用。

3:一旦缓存镜像不可用,则Dockerfile中的后续指令将被执行,并产生新的中间镜像。

下面就是一个利用缓存构建镜像的输出:

$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 0 : FROM alpine:3.2
---> 31f630c65071
Step 1 : MAINTAINER SvenDowideit@home.org.au
---> Using cache
---> 2a1c91448f5f
Step 2 : RUN apk update && apk add socat && rm -r /var/cache/
---> Using cache
---> 21ed6e7fbb73
Step 3 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
---> Using cache
---> 7ea8aef582cc
Successfully built 7ea8aef582cc

二:格式:

Dockerfile的格式如下:

# Comment
INSTRUCTION arguments

指令不区分大小写。但是,一般约定为全部大写,以便与其参数区分开。

以”#”作为开头的行,将被视为注释行。如果”#”出现在行中间,则将会被视为参数。

三:常用指令:

1:FROM

Dockerfile中,第一条指令必须是”FROM”,以便指定基础镜像。所谓基础镜像,就是没有父镜像的镜像。 FROM指定镜像基于哪个基础镜像创建。比如

FROM ubuntu

这表示新的镜像将基于Ubuntu的镜像来构建。

2:MAINTAINER

一般情况下,FROM指令的下一条指令就是” MAINTAINER”指令。用于指定新镜像的作者:

MAINTAINER <name>

3:RUN

在shell或者exec的环境下执行的命令。有两种格式:

RUN <command>       (shell form, the command is run in a shell - /bin/sh -c)
RUN ["executable", "param1", "param2"] (exec form)

RUN指令会在新创建的镜像上添加新的层面,接下来提交的结果用在Dockerfile的下一条指令中。

4: ADD

复制文件指令。它有两个参数<source>和<destination>。<destination>是容器内的路径,而<source>可以是一个URL,或者是上下文中的一个文件。ADD指令将<source>所表示的文件或者目录添加到容器的<destination>中。

注意:

a:如果<src>是本地文件,则该文件必须位于上下文中。

b:如果<src>是目录,在目录中的所有内容都会复制到容器中。

c:如果<src>是本地的一个tar压缩文件,则复制时会将其解压。

d:如果<dest>不存在,则会在容器中创建,包括其中包含的目录。

5:CMD

提供了容器默认的执行命令。有三种格式,推荐exec格式:

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)

Dockerfile只允许使用一次CMD指令。如果有多个CMD指令,则只有最后一个指令生效。

CMD指令主要用于提供运行容器时,该容器默认需要执行的命令。

如果使用的是CMD的shell形式,则CMD后的命令将以”/bin/sh -c”执行。若不希望在shell中执行,则CMD需要使用exec的形式,这也是更被提倡的做法。

如果用户在执行”docker  run”时提供了容器要运行的命令,则该命令会覆盖CMD的内容。

6:ENTRYPOINT

提供了容器默认的执行命令。有两种格式,推荐exec格式:

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)

在使用”dockerrun”命令运行容器时,指定的命令参数都会追加到exec形式的ENTRYPOINT中,并且会覆盖掉CMD中的内容。比如"docker run <image>-d",就会将”-d”追加到exec形式的ENTRYPOINT中。

shell形式的ENTRYPOINT会覆盖掉CMD或者”dockerrun”中的命令。但是这种形式的命令是在”/bin/sh -c”下执行的。

只有最后一个ENTRYPOINT会起作用。

可以在ENTRYPOINT中指定容器要执行的命令和参数,并在CMD中指定该命令的其他参数,比如:

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

虽然CMD和ENTRYPOINT都用来指定容器运行时的指令。但是它们又有不同的意义:

a:Dockerfile中应该至少指定一个CMD或者ENTRYPOINT;

b:CMD中可用于指定ENTRYPOINT中命令的参数;如果使用”docker run”指定了容器运行指令,则它会覆盖掉CMD中的内容。

下表描述了ENTRYPOINT和CMD相互作用的结果:

7:EXPOSE

指定容器在运行时监听的端口。语法如下:

EXPOSE <port> [<port>...]

注意,EXPOSE指令并不指定容器与主机间的端口映射。要想指定端口映射,必须在docker run时使用-p或-P参数。

8:ENV

设置环境变量。有两种格式:

ENV <key> <value>
ENV <key>=<value> ...

该指令将环境变量<key>设置为<value>。该环境变量在Dockerfile后续的指令中保持有效。该环境变量在容器运行时也保持有效。

四:注意

1:Dockerfile中,通过ENTRYPOINT和CMD指定的容器默认运行程序,比如apache、redis等,如果以后台的方式运行,则该容器启动后会立即结束,因为容器运行时,必须要有一个前台程序。

2:容器中应该只运行一个进程;

五:例子

下面是一个制作redis镜像的Dockerfile:

FROM oraclelinux:6.6
MAINTAINER hehe RUN yum update –y && yum -y install redis ADD redis.conf /etc/redis.conf EXPOSE 6379 CMD ["redis-server", "/etc/redis.conf"]

该Dockerfile很简单:

FROM指明该镜像以oraclelinux:6.6为基础镜像;

MAINTAINER指明镜像作者是hehe;

然后就是运行”yum –y install redis”命令安装redis;

接下来,使用ADD指令,将上下文中的redis.conf文件复制到容器中的/etc/目录下;

然后使用EXPOSE指明该镜像监听6379端口;

最后,使用CMD指明容器运行时的指令是”redis-server  /etc/redis.conf”

写好Dockerfile之后,使用下面的命令构建镜像:

docker build -t redis .

05Dockerfile简介的更多相关文章

  1. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  2. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  3. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

  4. REST简介

    一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...

  5. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  6. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  7. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  8. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  9. Cesium简介以及离线部署运行

    Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...

随机推荐

  1. memcache 拓展

    需要安装Libevent.memcached.memcache. 参考网址:https://www.cnblogs.com/hejun695/p/5369610.html 启动:/usr/local/ ...

  2. [转]深入理解ajax系列——进度事件

    一般地,使用readystatechange事件探测HTTP请求的完成.XHR2规范草案定义了进度事件Progress Events规范,XMLHttpRequest对象在请求的不同阶段触发不同类型的 ...

  3. [转]js的垃圾回收机制

    javascript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存.在编写javascript程序时,开发人员不用再关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管 ...

  4. 容斥原理学习(Hdu 4135,Hdu 1796)

    题目链接Hdu4135 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  5. “微信小程序” js部分注解

    1.小程序不提供获取dom的操作,而是让我们直接将事件绑定写入到组件内.区别在于bind不阻止冒泡,而catch阻止冒泡. <view id="tapTest" bindta ...

  6. CSS min-height 属性

    实例 设置段落的最小高度: p { min-height:100px; } 浏览器支持 IE Firefox Chrome Safari Opera 所有主流浏览器都支持 min-height 属性. ...

  7. Linux下安装jboss并设置自启动服务

    一.JDK和JBOSS下载jdk:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htm ...

  8. springMVC原理解析

    1:SpringMVC运行原理 2:工作流程 (1)客户端(浏览器)发送请求,直接请求到DispatcherServlet. (2)DispatcherServlet根据请求信息调用HandlerMa ...

  9. web前端学习(二)html学习笔记部分(8)--服务器推送事件3

    1.2.22  html5服务器推送事件 1.2.22.1  html5服务器推送事件介绍 服务器推送事件(Server-sent Events)是HTML5规范中的一个组成部分,可以用来从服务器端实 ...

  10. Android中使用ormlite实现持久化--HelloOrmLite

    Android中内置了sqlite,但是常用的开发语言java是面向对象的,而数据库是关系型的,二者之间的转化每次都很麻烦(主要是我对sql语言不熟悉).而Java Web开发中有很多orm框架,但是 ...