Docker之Dockerfile 指令详解
闲话不多说,dokerfile常用指令解析奉上
FROM
作用:指定基础镜像,必须放在DOckerfile的第一行,表示从哪个baseimage开始构建
格式:
FROM <image>:[tag]FROM <image>@<digest>
- 镜像必须是Dockerfile文件中第一条非注释指令,表示从哪个baseimage开始构建 FROM
- 指令能同一个Dockerfile文件中出现多次,为了创建多个镜像 tag 和 digest
- 值是可选的,如果缺省,构建器默认为latest,当tag不匹配时,构建器返回错误
MAINTAINER
作用:指定作者信息,该指令已被废弃但是目前还可以使用,可以用LABEL指令代替。
格式:
MAINTAINER <name>
eg.MAINTANER "cx55887 <chn1945@sina.com>"
LABEL
作用:设定一些添加镜像的元数据,LABEL是一对key-value值
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
eg.LABEL version="2.1"LABEL creator="cx55887"
镜像可以有多个LABEL,来指定多个标签,Docker建议在可能的情况下将 标签组合到单个LABEL指令中,
因为每一个LABEL指令都会产生一个新的层,而层数越多就会导致执行花费时间越长。
LABEL version="2.1" \creator="cx55887" \other="value"
LABEL中如果key已存在,后面添加相同的key那么新的value会覆盖掉前面的。
COPY
作用:将工作目录下的文件复制到所做的镜像中的文件系统中
格式:
COPY [--chown=<user>:<group>] <源路径>... <目标路径>COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
- <源路径>用相对路径,可以用通配符, 源文件必须在工作目录或者工作目录的子目录中,<目标路径> 可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)
- 目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
- 如果源文件是一个目录,会自动递归复制目录下的文件到目标位置,但是目录自身不会复制
- 如果复制多个文件,或者源文件中用了通配符,那么目标路径必须以 / 为结尾
- 此外,还需要注意一点,使用 COPY指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git进行管理的时候。
在使用该指令的时候还可以加上 --chown=: 选项来改变文件的所属用户及所属组。
COPY --chown=cx55887:cx55887 files* /mydir/COPY --chown=cx55887 files* /mydir/COPY --chown=1 files* /mydir/COPY --chown=10:11 files* /mydir/
ADD
作用:和COPY类似,可以实现将文件和目录复制到镜像中,但是区别是可以实现:
如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。
如果<源路径>是一个URL,Docker引擎会去下载这个链接的文件放到<目标路径>,下载后文件的权限自动设置为600。注意:下载的tar包不会自动解压
格式:
ADD [--chown=<user>:<group>] <源路径>... <目标路径>ADD [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
使用ADD指令的时候也可以通过--chown=<user>:<group>
选项廖改变文件的属主和属组
ADD --chown=cx55887:cx55887 files* /mydir/ADD --chown=cx55887 files* /mydir/ADD --chown=1 files* /mydir/ADD --chown=10:11 files* /mydir/
WORKDIR
作用:设置镜像中的工作目录,相当于cd命令
格式:
WORKDIR <工作目录路径>
- WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR会帮你建立目录。
VOLUME
作用:指定数据卷的挂载点,若不存在会自动创建
格式:
VOLUME ["<路径1>", "<路径2>"...]VOLUME <路径>
eg.VOLUME /data
这样/data目录就会在运行的自动挂载,任何向/data写入的信息都不会记录进容器储存层,从而保证容器储存层的无状态化,当然运行时可以覆盖掉这个挂载设置:
docker run -d -v mydata:/data xxxx
在这条命令中,就使用了mydata 这个命名卷改在到了/data这个位置,替代了 Dockerfile中定义的匿名卷的挂在配置
EXPOSE
作用:告诉 Docker 服务端 容器对外映射的本地端口。
格式:
EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在dockerfile中声名有两个好处:
- 帮助镜像使用者理解这个镜像服务的守护端口,方便配置映射
- 运行时使用随机端口映射时,也就是
docker run -P
时,会随机映射EXPOSE
中声明的端口。 - 另外需要注意的是将
EXPOSE
和在运行时使用-p <宿主端口>:<容器端口>
区分开,-p
是映射宿主端口和容器端口,也就是说将容器的对应端口服务公开给外界访问,而EXPOSE
仅仅是声名容器打算使用那些端口而已,并不会自动在宿主机进行端口映射
ENV
作用:设置环境变量
格式:
ENV <key> <value>ENV <key1>=<value1> <key2>=<value2> ...
eg.ENV VERSION=1.0 DEBUG=no \NAME="cx baby"
通过ENV所定义的变量是可以传递到容器之中,但是,在创建容器的时候,如果手动指定了变量的值,那么这个值会覆盖掉镜像中原有的值
RUN
作用:RUN指令会在当前镜像的基础上指定命令,并提交为新镜像
格式:
RUN <command> RUN ["executable","param1","param2"]
前者将在shell终端中运行命令,即/bin/sh -c
;后者则使用exec执行。指定使用其它终端可以通过第二种方式实现,例如RUN ["/bin/bash", "-c", "echo hello"]
。
CMD
作用:定义容器启动以后要默认运行的程序,即pid为1的程序
格式:
shell 格式:CMD <命令>
exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
我们知道Docker不同于虚拟机,容器就是进程,既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD指令就是指定容器主进程启动命令的。
在运行的时候可以指定新的命令来替代镜像设置中的这个默认命令,比如ubuntu镜像的默认的CMD是/bin/bsah,如果我们直接docker run -it ubuntu的话,会进入bash 。我们也可以在运行时指定运行别的命令,如 docker run ubuntu cat /etc/os-release。这就是用 cat /etc/os-release 命令替换了默认的/bin/bash 命令输出了系统版本信息。
在指令格式上,推荐使用exec格式,这类格式在解析是会被解析成JOSN数组,因此一定要使用双引号,而不要使用单引号。
如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:
CMD echo $NAME
在实际执行中,会将其变更为:CMD [ "sh" ,"-c", "echo $NAME"]
这就是为什么我们可以使用环境变量的原因,因为这些环境变量会被 shell 进行解析处理。
提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。
一些初学者将CMD写为:
CMD server nginx start
然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为 CMD [ “sh”, “-c”, “service nginx start”],因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
CMD [“nginx”, “-g”, “daemon off;”]
ENTRYPOINT
作用:ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中执行)
- 在运行RUN的时候所执行的命令无法覆盖ENTRYPOINT中的命令 RUN
- 后面的命令会被以参数的方式追加到原本要执行的命令的末尾,而不是替换
ARG
作用:定义在构建镜像时候所使用的变量,在将来容器运行时是不会存在这些环境变量的。
格式:
ARG <参数名>[=<默认值>]
Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。
USER
作用:定义容器中的进程以哪个用户的身份运行
格式:
USER <用户名>[:<用户组>]
该用户必须存在于容器的用户空间中(容器的文件系统的中的/etc/passwd中)
HEALTHCHECK
作用:HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在 HEALTHCHECK 指令检查成功后变为 healthy,如果连续一定次数失败,则会变为 unhealthy。命令的返回值决定了该次健康检查的成功与否:0:成功;1:失败;2:保留,不要使用这个值。
HEALTHCHECK 支持下列选项:
--interval=<间隔>:两次健康检查的间隔,默认为 30 秒;--timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;--retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
ONBULID
作用:定义一个触发器,用来实现当基于这个这个镜像做新镜像的时候要执行的命令
格式:
ONBUILD <其它指令>
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
------做运维之前很矫情的小年轻-----
Docker之Dockerfile 指令详解相关推荐
- Docker学习——Dockerfile 指令详解(五)
2019独角兽企业重金招聘Python工程师标准>>> 我们已经介绍了 FROM (指定基础镜像) , RUN(执行命令) ,还提及了 COPY , ADD ,其实 Dockerfi ...
- Dockerfile 指令详解1
Dockerfile 指令详解 我们已经介绍了 FROM,RUN,还提及了 COPY, ADD,其实 Dockerfile 功能很强大,它提供了十多个指令.下面我们继续讲解其他的指令. COPY 复制 ...
- 【Docker】之 Dockerfile 指令详解
目录 Dockerfile 基本结构 Dockerfile 指令 指定基础镜像 FROM 维护者信息 MAINTAINER 元数据标签 LABEL 设置环境变量 ENV 镜像构建参数 ARG 指定工作 ...
- Dockerfile指令详解镜像构建实例说明
Dockerfile使用总结 Dockerfile是用来构建镜像的文本文件,里面包含了一条条用于构建镜像所需的指令和说明. Dockerfiel文件中的每一层指令都是描述如何在上一层的基础上进行该层的 ...
- Docker学习总结(32)——Dockerfile指令详解
1.ADD 复制文件 ADD指令用于复制文件,格式为: ADD <src>... <dest> ADD ["<src>",... "& ...
- 【Docker】Dockerfile用法详解
制作Docker image 有两种方式:一是使用 Docker container,直接构建容器,再导出成 image 使用:二是使用 Dockerfile,将所有动作写在文件中,再 build 成 ...
- Dockerfile 指令详解2
ENV 设置环境变量 格式有两种: ENV <key> <value> ENV <key1>=<value1> <key2>=<val ...
- Dockerfile指令详解:WORKDIR 指定工作目录
WORKDIR 指定工作目录 格式为 WORKDIR <工作目录路径>. 使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不 ...
- Dockerfile指令详解: CMD 容器启动命令
CMD 容器启动命令 CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式:CMD <命令> exec 格式:CMD ["可执行文件", "参 ...
最新文章
- conda如何添加,删除镜像channel,以及其他常见使用方法。
- codevs——1958 刺激
- Python Flask-表单提交方式
- Cocos2d—X游戏开发之VS2010 控制台输出中文,模拟器中文乱码问题解决
- linux 终端复用神器-tmux使用梳理
- 职称计算机为啥要现场拍照,网上确认/现场确认的照片还没拍?你需要这份拍照攻略!...
- linaro 网站资源
- 基于Java坦克大战小游戏设计(3)
- 计算机地图制图期末考试题,计算机地图制图原理思考题.doc
- 一文熟悉 Go 的循环结构 —— for 循环
- 雷达探测项目仿真代码(Matlab代码实现)
- java web: 上午 org.apache.catalina.core log 信息: 将servlet[***]标记为不可用/或者XXX资源不可用
- 5种RS485切换方向的方法及优劣势分析
- 极客日报:小米计划3年内成为全球第一;谷歌计划在韩国开放第三方支付;Firefox 94发布
- CAS-基于数据库认证
- idea下载数据库驱动太慢?
- (一)Activiti 数据库25张表——流程历史记录表25(ACT_EVT_LOG)
- 判断piv_str1是否包含在piv_str2中,成功返回值大于1,失败返回0
- PADS 找不到FileDir INI文件条目指定的目录
- Discuz(社区动力)论坛伪静态规则