Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制额外的需求时,只需Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。

Dockerfile的书写规则和指令的使用方法

# 注释
INSTRUCTION argument 12

指令忽略大小写,建议使用大写;每一行只支持一条指令,每条指令可以携带多个参数。Dockerfile的指令根据作用可以分为两种:构建指令和设置指令。

构建指令(用于构建镜像,其指定的操作不会在由镜像运行的容器上执行)

(1) FROM(指定基础镜像)

FROM必须是第一条非注释指令,它指定基础镜像且指定的镜像是已存在的。

格式:

FROM <image>                       # 指定基础镜像

FROM <image>:<tag>                 # 指定一个tag版本的基础镜像123

例子:

FROM ubuntu:14.041

(2)MAINTAINER(指定镜像创建者信息)

指定镜像的作者和联系方式信息。

格式:

MAINTAINER <author> "e-mail"      # 指定作者名和E-mail1

例子:

MAINTAINER locutus "locutus@foxmail.com"   

# 执行 #docker inspect image,输出中有相应的字段记录该信息123

(3)RUN(安装软件用)

RUN可以运行任何被基础镜像支持的命令。如基础镜像选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。

格式:

RUN <command> 

# shell模式,以#/bin/sh -c command 形式执行, 如RUN echo hello
RUN ["executable", "param1", "param2" ... ] # exec模式,指定其他形式的shell来运行指令 ,如RUN ["/bin/bash" ,“-c”,“echo hello" ]1234567

例子:

RUN apt-get update && apt-get install -y nginx     # 合并执行命令1

(4)ENV(用于设置环境变量)

在镜像中设置一个环境变量。

格式:

ENV  <key>  <value>      

# 设置后,后续RUN命令都可使用环境变量所输出的指令,容器启动ENV <key>=<value>后,通过#docker inspect查看环境变量,也可以通过
# docker run --env key=value设置或修改环境变量。 123

例子:

ENV  JAVA_HOME  /path/to/java/dirent       

# 在容器中安装JAVA程序,设置JAVA_HOME123

(5)ADD COPY(将本地文件或目录复制到由dockerfile构建的镜像中)

所有拷贝到container中的文件和文件夹权限为0755,uid和gid为0;如果是一个目录,那么会将该目录下的所 有文件拷贝到目录下,不包括目录;如果是文件且中不使用斜杠结束,则会将视为文件,的内容会写入;如果是文件且中使用斜杠结束,则会文件拷贝到目录下。

格式:

ADD  <src>  <dest>             

# <src>可以是文件或目录的本地地址(即Dockerfile所在目录的相对路径),也可以是一个远程的url(docker不推荐,更建议使用wget或curl获取文件); <dest>是镜像中的绝对路径                                                                                                                 

ADD  ["<src>" "<dest>"]                

# 适用于文件路径中有空格的情况,同理有COPY的情况

COPY <src>  <dest> 

COPY ["<src>" "<dest>"] 1234567891011

ADD与COPY的区别:ADD指令包含类似tar的解压功能,而COPY只单纯复制文件。

例子 :

# vim   index.html                          # 编辑一个index.html文件
<html>
<head>
<title>Page Added in Dockerfile</title>
</head>
<body>
<h1>I'm page in nginx_test1</h1>
</body>
</html> # 在Dockfile中写下 COPY index.html /usr/share/nginx/html/ # copy Dockerfile所在目录的文件到容器的绝对路径下,使用docker build 指令后,运行容器,查看端口映射,并# curl http://127.0.0.1:host_port 可以看到index.html的内容 123456789101112131415

设置指令(用于设置image的属性,其指定的操作将在由image运行的容器中执行)

(6)CMD(提供容器运行的默认命令)

提供容器运行的默认命令。与RUN类似,但RUN指定的命令是在容器构建过程中运行,而CMD指定的命令是在容器运行过程中运行。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。

格式:

CMD   ["executable","param1","param2"]         # exec模式  

CMD   command param1 param2                    # shell模式 

CMD   ["param1","param2"]                      

# 当Dockerfile指定了ENTRYPOINT时使用,其作为ENTRYPOINT指令的默认参数 1234567

例子:

# docker  run  --name  test  -d   repository  cmd                   //构建容器中的CMD指令被run的cmd覆盖,不会执行

# docker  run  --name  test  -d   repository                         //执行构建容器中的CMD指令123

(7)ENTRYPOINT(提供容器运行的默认命令)

指定容器运行时执行的命令,可以多次设置,但是只有最后一个有效。

格式:

ENTRYPOINT ["executable", "param1", "param2"]         

# exec模式

ENTRYPOINT command param1 param2                       

# shell模式  1234567

例子:

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

a. 当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那CMD指令和ENTRYPOINT会互相覆盖,只有最后一个CMD或者ENTRYPOINT有效。构建容器中的ENTRYPOINT指令不会被run的cmd覆盖,ENTRYPOINT指令仍会执行。

CMD   echo “Hello, World!”                         

ENTRYPOINT  ls  -l                                                          

# CMD指令将不会被执行,只有ENTRYPOINT指令被执行12345

b. 与CMD指令配合使用来指定ENTRYPOINT的默认参数。ENTRYPOINT指令只能使用exec模式,指定执行命令,而不能指定参数;CMD指令不是一个完整的可执行命令,仅仅是参数部分。

在Dockerfile中,写如下内容:

FROM ubuntu  

ENTRYPOINT ["/usr/bin/nginx"]  

CMD ["-h"]       12345

在命令行中,执行以下命令

# docker build -t="locutus1/nginx"  .    # 构建docker镜像

# docker run -p 80 --name nginx_test2 -d locutus1/nginx -g "daemon  off;"                                                             

# docker ps -l                                                           12345

命令# docker run 的-g “daemon off;” 指令将CMD中的-h指令覆盖。

(8)USER(设置container容器的用户)

设置启动容器的用户,默认是root用户。

格式:

USER  user
USER uid
USER user:group
USER uid:gid
USER user:gid
USER uid:group 123456

例子:

ENTRYPOINT ["memcached"]      # 指定指令memcached的运行用户为daemon
USER daemon 或 ENTRYPOINT ["memcached", "-u", "daemon"] 123456

(9)EXPOSE(指定容器需要映射到宿主机的端口)

该指令会将容器中的端口映射成宿主机中的某个端口。当你需要访问容器的时候,可以不使用容器的IP地址而是使用宿主机的IP地址和映射后的宿主机端口。要完成整个操作需要两个步骤:

\1. 在Dockerfile使用EXPOSE设置需要映射的容器端口

\2. 在运行容器的时候指定-p选项和EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。

格式:

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

例子:

EXPOSE port1                         // 映射一个端口  

# docker run -p port1 image          // 运行容器使用的相应命令   123
EXPOSE port1 port2 port3             //映射多个端口  

# docker  run  -p  port1  -p  port2    -p   port3  image                                       

// 运行容器使用的相应命令   

# docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3  image
//指定需要映射到宿主机上的某个端口号 # docker port port1 containerID //对于一个运行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID来查看该端口号在宿主机器上的映射端口123456789101112

端口映射是docker比较重要的一个功能,原因在于我们每次运行容器时容器IP地址不能指定而是在桥接网卡的地址范围内随机生成的。宿主机器的IP地址是固定的,我们可以将容器的端口的映射到宿主机的一个端口,免去每次访问容器中的某个服务时都要查看容器的IP的地址。

(10)VOLUME(指定挂载点)

使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时,可以在Dockerfile中使用该指令。

格式:

VOLUME ["<mountpoint>"]  1

例子:

VOLUME ["/tmp/data"]  1

运行通过该Dockerfile构建镜像的容器,/tmp/data目录中的数据在容器关闭后,里面的数据还存在。

如果另一个容器也有持久化数据的需求,且想使用上述容器共享的/tmp/data目录,那么可以运行下面的命令启动一个容器。

# docker run -it -rm -volumes-from container1 image2   /bin/bash       

//container1为第一个容器的ID,image2为第二个容器运行image的名字。    123

(11)WORKDIR(切换目录)

可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。

格式:

WORKDIR /path/to/workdir    

// 一定要使用绝对路径,如果使用相对路径,那么路径会传递下去

WORKDIR   a
WORKDIR b
WORKDIR c // 相当于#cd /a/b/c 123456789

例子:在Dockerfile中写入以下

WORKDIR /path/to/p1
WORKDIR p2
RUN vim a.txt // 在/p1/p2下,执行# vim a.txt 12345

(12)ONBUILD(镜像触发器)

当一个镜像被其他镜像作为基础镜像执行时,新的镜像会在构建过程中插入ONBUILD触发器中的指令

格式:

ONBUILD <Dockerfile关键字>                    

// ONBUILD指定的命令在由Dockerfile构建原镜像时并不执行,而是在由原镜像被其他镜像作为基础镜像构建时执行 123

例子:

# vim Dockerfile
...
ONBUILD COPY index.html /usr/share/nginx/html/
... # docker build -t="locutus1/nginx4" . //构建原镜像locutus1/nginx4 # docker run -p 81 --name nginx4 locutus1/nginx4 # curl http://127.0.0.1:host_port
// 依旧是原来nginx的内容,说明在构建时虽然显示,但没有 执行 ONBUILD COPY index.html /usr/share/nginx/html/ # vim Dockerfile FROM locutus1/nginx4
// 原镜像locutus1/nginx4作为locutus1/nginx5的基础镜像
... # docker build -t="locutus1/nginx5" .
//在step0后,执行了触发器的指令COPY # docker run -p 82 --name nginx4 locutus1/nginx5 # curl http://127.0.0.1:host_port
//是COPY指令所复制的index.html的内容了

Dockerfile的书写规则和指令的使用方法的更多相关文章

  1. Dockerfile的书写规则及指令使用方法

    Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docker程序将读取Dockerfile,根据指令生成定制的ima ...

  2. dockerfile简介及书写规则

                                       Dockerfile 简介 Dockfile是一种被Docker程序解释的脚本, Dockerfile由一条一条的指令组成,每条指 ...

  3. 很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序

    很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用m ...

  4. 学习Shell脚本编程(第1期)_Shell命令行书写规则

    Shell命令行的书写规则 对Shell命令行基本功能的理解有助于编写更好的Shell程序,在执行Shell命令时多个命令可以在一个命令行上运行,但此时要使用分号(:)分隔命令,例如: [root@l ...

  5. Linux makefile教程之书写规则三[转]

    书写规则———— 规则包含两个部分,一个是依赖关系,一个是生成目标的方法.在 Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来 ...

  6. Route@书写规则的总结

    路由书写规则的总结 概念:Routing System由一组路由组成,每一个路由规则可以匹配一种类型的URL,在请求过来的时候,Ruting ystem 就用它来处理这个URL,路由的任务就是匹配UR ...

  7. happens-before规则和指令重排

                                                                                                         ...

  8. web.xml文件书写规则

    在为class文件写xml配置文件的书写规则,需要书写的东西如下 <servlet> <servlet-name></servlet-name> <servl ...

  9. 1、Shell命令行书写规则

    学习目标Shell命令行书写规则 正文对Shell命令行基本功能的理解有助于编写更好的Shell程序,在执行Shell命令时多个命令可以在一个命令行上运行,但此时要使用分号(;)分隔命令,例如: ro ...

随机推荐

  1. java中什么是代码点,什么是代码单元?

    1.代码点&代码单元,是从Unicode标准而来的术语,Unicode标准的核心是一个编码字符集,它为每一个字符分配一个唯一数字.Unicode标准始终使用16进制数字,并且在书写时在前面加上 ...

  2. Linux-shell实现阳历转农历(序)

    好些天没有登陆邮箱,前几天上班打开一看垃圾箱中有一封邮件让我好激动,还是国外友人的英文邮件.^_^大概内容是我早些时候写的一个阳历转农历的shell小程序,他在用的时候发现了bug,但是这个bug我在 ...

  3. Repeater控件最后一笔记录高亮显示

    Insus.NET以前有写过 <Repeater控件第前10笔记录高亮显示> 不过,现在有一个想法,就是最后一笔记录高亮显示,怎样实现? 技术要求,就是获取最后一笔的索引即可.可以从数据源 ...

  4. UWP&WP8.1图片照片添加水印

    水印可以自己自己制作,也可以用代码写. 我这里主要写如何添加到照片上面. UWP和WP8.1添加的方法一样.代码是通用的. UWP和WP8.1没有像WPF和WINFROM中darw这样简便的API可以 ...

  5. Git master branch has no upstream branch的解决

    Git master branch has no upstream branch的解决 在push代码时,出现“git master branch has no upstream branch”问题的 ...

  6. 【转】c# 读取excel数据的两种方法

    源地址:http://www.cnblogs.com/icyJ/p/ReadExcel.html

  7. Internet路由-主机路由表和转发表

    1.路由表 路由信息最终要存储在用于路由器的主机或者专业路由器上,存放这些信息的地方称为路由表.其中包含三元素:目标地址,掩码,下一跳. 1.1.查询路由表的开销 有人认为查询路由表是一件和交换机查询 ...

  8. BZOJ 2725 [Violet 6]故乡的梦 线段树+最短路树

    \(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) \(\color{#0066ff}{输出格式}\) \(\color{#0066ff}{输入 ...

  9. 二维树状数组总结&&【洛谷P4514】 上帝造题的七分钟

    P4514 上帝造题的七分钟 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了00的n×mn×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b)(a,b),右下 ...

  10. 关于如何在Windows下测交互题

    这里的交互题指的NOI风格的交互题,即交互库 codeforces风格的交互题...只能自己实现评测插件了 使用Cena,Lemon没有附加文件功能不能评测交互题 在编译选项g++编译命令源文件中加入 ...