文章目录
-
- 一、什么是Dockerfile
- 二、解析nginx的Dockerfile语法
-
- FROM
- LABEL
- ENV
- RUN
- COPY
- ENTRYPOINT
- EXPOSE
- STOPSIGNAL
- CMD
一、什么是Dockerfile
Dockerfile是自动构建docker镜像的配置文件,将镜像构建过程通过指令的方式定义在Dockerfile中。配合命令行可以实现自动化的Docker镜像的构建。
上图是nginx:1.20.2版本docker镜像的Dockerfile,下面我们来逐行解析。
二、解析nginx的Dockerfile语法
我们在学习一门语言或文档语法的时候,最快的学习方式就是看别人是怎么写的。这里这个“别人”是谁就很重要,跟着臭棋篓子下棋越下越臭。所以学习Dockerfile语法,我们有必要找一个模范:大家可以去Dockerhub看一下那些开源软件官方提供的镜像,都可以找到对应的Dockerfile,看看别人是怎么写的。
我们就以上文中的nginx:1.20.2版本docker镜像的Dockerfile( 官方提供的),我们来逐行解析它的语法及构建过程。
FROM
一般我们构建镜像的都需要一个基础的linux操作系统的发行版镜像,并且在此基础上我们构建自己的镜像。
所以FROM指令的作用就是指定基础镜像,nginx这里使用的基础linux镜像是。其中是debian的linux发行本操作系统的一个版本,版本名称叫做bullseye。通常是指这个镜像是该发行版本中的最小安装版本,因为我们构建完成的镜像是要在后续的持续集成过程中,以及仓库和docker服务器之间 络传播的,所以尽可能让镜像的构建结果size最小化。基础镜像的选择要着重考虑size的大小,满足linux基本功能及你的程序运行的前提下越小越好。
LABEL
LABEL用于给当前镜像添加一些描述、解释性信息,如:当前镜像的维护人及联系方式等信息。用键值对的方式自定义,一行可以定义多个。
也可以定义多行,如maintainer维护人信息,description镜像描述信息。如果描述信息一行写不下,可以用“”换行。Dockerfile语法中有一个指令叫做MAINTAINER,专门用于描述该镜像的维护人信息,但是现在已经不建议使用了,统一使用LABEL。
ENV
ENV的作用是设置环境变量,该环境变量设置之后,可以在构建过程及容器运行时的shell脚本中使用该变量,使用方法如:。学过JAVA的同学想想你的JAVA_HOME环境变量怎么设置的以及怎么使用的NV是同样的道理。只不过放到docker这里语法发生了变化而已,语法格式:。
RUN
RUN指令的作用就是执行linux的shell脚本,通过下图可以看到在shell脚本中可以使用通过ENV定义的环境变量。
ENTRYPOINT
一个Dockerfile中如果定义多个ENTRYPOINT,只有最后一条ENTRYPOINT生效,并且每次启动docker容器,都会执行ENTRYPOINT指定的脚本。对于nginx:1.20.2而言,”/docker-entrypoint.sh”脚本中定义了nginx配置检查及nginx服务的启动指令。所以通常情况下ENTRYPOINT指定的脚本通常都是镜像内核心服务的启动脚本。
这个脚本中最后执行了nginx服务启动,需要配合CMD命令完成,参考下文的CMD命令。
EXPOSE
Docker 容器在运行时暴漏指定的 络端口,可用于容器端口映射,默认协议是 TCP。格式如下:
将容器端口暴露出去后,可以与宿主机的端口建立映射关系,这样可以通过访问宿主机的端口来访问容器内部的服务。比如同时在 TCP、UDP 上暴露容器的80端口。
STOPSIGNAL
这个指令笔者也并不常用,我查询了docker-nginx在github上的issues里面给出的答案是,之所以加上STOPSIGNAL信 的目的是:避免docker容器停止后,nginx服务不能正确终止造成僵尸进程的存在。
CMD
CMD指令也是用来执行linux命令或脚本,这一点和RUN指令是一致的。二者的区别在于
- CMD指令是在执行指令时被执行,也就是创建容器时执行;而RUN指令实在镜像构建的时候执行,即时候执行。
- 也正因为指令的执行期不同,RUN命名执行的写入操作被写入到镜像层。CMD指令执行结果包含写入操作,被写入到容器层。(可以参考我之前文章《镜像分层原理》学习理解)。
- 所以CMD和ENTRYPOINT 指令有点相似,都是在创建容器时运行。需要注意的是:一旦Dockerfile中包含ENTRYPOINT指令,CMD指令就作为ENTRYPOINT指定的脚本的参数存在。参考下文格式语法。
CMD包含三种格式:
- 第一种为ENTRYPOINT指定的脚本传参,上文中的ENTRYPOINT脚本最后一行的就是在执行CMD传递的命令及参数。来完成nginx服务的启动。这种用法是各官方Dockerfile常用的做法(如:nginx、redis),就是在ENTRYPOINT指定的脚本中做一些配置准备工作,然后在ENTRYPOINT脚本的最后一行通过调用CMD命令进行容器服务的启动。
- 第二种 执行一个命令或shell脚本,可以传参,注意是双引 。与第一种格式语法是一样的,只是没有ENTRYPOINT指定脚本,所以不作为ENTRYPOINT指定脚本的参数存在。
- 第三种为普通的执行shell脚本的语法,如执行shell命令行。笔者说:在Dockerfile中这种方法不要用,没必要知道为什么。
文章知识点与官方知识档案匹配,可进一步学习相关知识云原生入门技能树容器(docker)安装docker8587 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!