Dockerfile的书写规则和指令的使用方法
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的书写规则和指令的使用方法的更多相关文章
- Dockerfile的书写规则及指令使用方法
Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令.Docker程序将读取Dockerfile,根据指令生成定制的ima ...
- dockerfile简介及书写规则
Dockerfile 简介 Dockfile是一种被Docker程序解释的脚本, Dockerfile由一条一条的指令组成,每条指 ...
- 很详细、很移动的Linux makefile教程:介绍,总述,书写规则,书写命令,使用变量,使用条件推断,使用函数,Make 的运行,隐含规则 使用make更新函数库文件 后序
很详细.很移动的Linux makefile 教程 内容如下: Makefile 介绍 Makefile 总述 书写规则 书写命令 使用变量 使用条件推断 使用函数 make 的运行 隐含规则 使用m ...
- 学习Shell脚本编程(第1期)_Shell命令行书写规则
Shell命令行的书写规则 对Shell命令行基本功能的理解有助于编写更好的Shell程序,在执行Shell命令时多个命令可以在一个命令行上运行,但此时要使用分号(:)分隔命令,例如: [root@l ...
- Linux makefile教程之书写规则三[转]
书写规则———— 规则包含两个部分,一个是依赖关系,一个是生成目标的方法.在 Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来 ...
- Route@书写规则的总结
路由书写规则的总结 概念:Routing System由一组路由组成,每一个路由规则可以匹配一种类型的URL,在请求过来的时候,Ruting ystem 就用它来处理这个URL,路由的任务就是匹配UR ...
- happens-before规则和指令重排
...
- web.xml文件书写规则
在为class文件写xml配置文件的书写规则,需要书写的东西如下 <servlet> <servlet-name></servlet-name> <servl ...
- 1、Shell命令行书写规则
学习目标Shell命令行书写规则 正文对Shell命令行基本功能的理解有助于编写更好的Shell程序,在执行Shell命令时多个命令可以在一个命令行上运行,但此时要使用分号(;)分隔命令,例如: ro ...
随机推荐
- 数据结构 Job
问题描述 有 n 项工作在等待队列中等待处理,编号为 1-n. 每个工作有个优先级 p.处理机同一时间只能处理一项工作.处理机决定接下来处理哪一项工作的方式为:从队首取出一项工作 x,若等待队列中没有 ...
- 记一次OOM问题排查过程
上周运维反馈线上程序出现了OOM,程序日志中的输出为 Exception in thread "http-nio-8080-exec-1027" java.lang.OutOfMe ...
- Django之高级视图与URL
Urls.py中有我们所有的路由映射关系.但是随着网站功能的增多,需要配置的URL也变得多了起来.并且维护这些导入也变得很麻烦.因此介绍一些优化和简洁的方法: 一 使用多个视图前缀: 之前所有的路由关 ...
- Swift3.0 UICollectionView简单使用
感觉swift各版本语法改动太大,储备着吧
- Java从入门到放弃——03.循环和判断
本文目标 选择结构:if,switch 循环结构:for , foreach ,while,do while 跳出语句:break,continue 1.选择结构 if: if(判断语句){ } s ...
- codevs1169, 51nod1084(多线程dp)
先说下codevs1169吧, 题目链接: http://codevs.cn/problem/1169/ 题意: 中文题诶~ 思路: 多线程 dp 用 dp[i][j][k][l] 存储一个人在 (i ...
- Java泛型<>内各种参数的异同
先说下本篇随笔主要涉及到的东西(参考Java编程思想一书): 1.说明 List<Fruit> 与 List<Apple> 之间为什么是非继承关系. 2.由 1 引出的问题说明 ...
- 公有云Docker镜像P2P加速之路:安全篇
一.问题 在使用Docker运行容器化应用时,宿主机通常先要从Registry服务(如Docker Hub)下载相应的镜像(image).这种镜像机制在开发环境中使用还是很有效的,团队成员之间可以很方 ...
- [转载]C#实现获取浏览器信息
原文地址:C#实现获取浏览器信息作者:flywithme Request.Browser.MajorVersion.ToString();//获取客户端浏览器的(主)版本号 Request.Bro ...
- kuangbin专题十六 KMP&&扩展KMP HDU1358 Period
For each prefix of a given string S with N characters (each character has an ASCII code between 97 a ...