05Dockerfile简介
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简介的更多相关文章
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Cassandra简介
在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...
- REST简介
一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...
- Microservice架构模式简介
在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- HTTPS简介
一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...
- 【Machine Learning】机器学习及其基础概念简介
机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- Cesium简介以及离线部署运行
Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...
随机推荐
- Web基础了解版06-Jsp
Jsp Jsp全称Java Server Pages,也就是在我们JavaWeb中的动态页面. Jsp能够以HTML页面的方式呈现数据,是一个可以嵌入Java代码的HTML. Jsp其本质就是一个Se ...
- 关于JavaScript的一些不得不知道的事儿
1.JavaScript不区分整数和浮点数,统一用Number表示. 2.NaN这个特殊的Number与所有其他值都不相等,包括它自己: NaN===NaN; //false 唯一能判断NaN的方法是 ...
- sending data mysql slow Mysql查询非常慢的可能原因
1.用explain看看mysql的执行情况,可以得知,task_id扫描了近20万条数据,而且这个task_id不是索引 2.为这个task_id所在的表,将此字段添加索引后,查询就变得很快了
- Vue.js NPM 安装方法
由于 npm 安装速度慢,本教程使用了淘宝的镜像及其命令 cnpm,安装使用介绍参照:使用淘宝 NPM 镜像. npm 版本需要大于 3.0,如果低于此版本需要升级它: # 查看版本 $ npm -v ...
- 二分查找(BinSearch)的Javascript实现
二分查找 解析:二分查找,也为折半查找.对于一个从小到大排列的有序数组,首先要找到一个中间值,通过与中间值比较,大的放又,小的放在左边.再在两边中寻找中间值,持续以上操作,直到找到所在位置为止. 1. ...
- Codeforces 449B
题目链接 B. Jzzhu and Cities time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- Ubuntu下安装go语言
参考:http://golang.org/doc/install/source 1. 下载go源代码 sudo apt-get install mercurial hg clone -u releas ...
- .Net Core 授权系统组件解析
前面关于.Net Core如何进行用户认证的核心流程介绍完毕之后,.Net Core 认证系统之Cookie认证源码解析远程认证暂时不介绍,后期有时间,我会加上.接下去介绍认证组件是如何和认证组件一起 ...
- python实现统计字符类型
#字符串处理统计类型def my_func(*str): list_num = [] list_big = [] list_small = [] list_qt = [] str = input('请 ...
- Python中的进程池与线程池
引入进程池与线程池 使用ProcessPoolExecutor进程池,使用ThreadPoolExecutor 使用shutdown 使用submit同步调用 使用submit异步调用 异步+回调函数 ...