Docker入门:Dockerfile构建过程解析及案例演示
一、Dockerfile简介
Dockerfile是用来构建Docker镜像的文本文件,它是由一条一条构建镜像所需的指令和参数构成的脚本。
如上图所示,Dockerfile是独立于本地docker实例的一个文本文件,用于自动化地构建具有特定功能的docker镜像。
Dockerfile镜像构建三部曲:
(1)构建Dockerfile文件;
(2)采用docker build
命令构建镜像;
(3)采用docker run
命令依据镜像运行容器实例。
二、Dockerfile构建过程
2.1 Dockerfile内容基础知识
- 1、每条保留字指令都必须为大写字母且后面至少跟随一个参数;
- 2、指令按照自上而下顺序执行,其中
#
表示注释代码; - 3、每条指令都会创建一个新的镜像层并对镜像进行提交。
2.2 Docker执行Dockerfile的大致流程
- 1、Docker从基础镜像运行一个容器;
- 2、执行一条指令并对容器作出修改;
- 3、执行类似
docker commit
的操作提交一个新的镜像层; - 4、Docker再基于刚提交的镜像运行一个新容器;
- 5、执行dockerfile中的下一条指令直至所有指令执行完。
Dockerfile就是把单独的docker操作命令融入到一个Dockerfile脚本文件中,自动化的实现复杂的容器创建、操作与运行的过程。
2.3 Dockerfile、Docker镜像和Docker容器的关系
从应用软件开发角度来看,它们分别表示软件开发的三个阶段:
- (1)Dockerfile是软件开发的原材料;
- (2)Docker镜像是软件的交付品;
- (3)Docker容器是Docker交付镜像的实例化,代表软件的实际运行过程。
总结:Dockerfile面向开发,Docker镜像为交付标准,Docker容器与部署、运维相关,三则相辅相成缺一不可,他们是Docker的三大基石。Docker在实际运行中,Dockerfile、Docker镜像、Docker容器三者的运作内容如下所示:
- 1、Dockerfile定义了进程需要的一切内容,包括:代码执行、文件/环境变量、依赖包、运行环境、操作系统发行版本、服务进程、内核进程等等,很多与操作系统底层相关的内容。
- 2、通过
docker build
指令会生成一个Docker镜像,它是为用户提供各种服务的基础; - 3、Docker容器则是一个实例化的服务进程。
三、Dockerfile保留字简介
Dockerfile文件是由一条条保留字组成的配置信息组成,常用的Dockerfile保留字如下所示:
1、FROM
基本上都会出现在Dockerfile的第一行,用于表示新建的镜像来自于哪里,即它的父类是谁,用于根据已经存在的镜像作为模板。
2、MAINTAINER
镜像维护者的姓名及邮箱地址。
3、RUN
(1)容器构建时候需要运行的命令;
(2)包括两种格式:shell
格式和exec
格式
(3)RUN
是在docker build
时运行。
4、EXPOSE
当前容器对外暴露的端口。
5、WORKDIR
指定在创建容器后,终端默认登陆的近来工作目录,一个落脚点。
6、USER
指定该镜像以什么样的用户去执行,如果不指定,默认是root
。
7、ENV
用来在构建镜像过程中配置环境变量。这个环境变量可以在后缀的任何RUN
指令中使用,这就好比在命令前面指定了环境变量一样。比如下面指令:
ENV MY_PATHY /usr/mytest
WORKDIR $MY_PATH
上面的环境变量MY_PATH
指定为/usr/mytest
,后续可以直接使用MY_PATH
代替/usr/mytest
。比如,我们使用WORKDIR $MY_PATH
表示创建容器后,终端登陆的工作目录为/usr/mytest
。
8、ADD
将宿主机目录下的文件拷贝到镜像内部,并且会自动处理URL
和解压tar
压缩包。
9、COPY
与ADD
相似,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>
的文件或目录复制到新的一层镜像内的<目标路径>
中。其指令格式如下所示:
COPY src dest
或者
COPY ["src", "dest"]
(1)src
:源文件或者源目录
(2)dest
:容器内的指定路径,这个路径不用事先构建好,执行指令的时候会自动创建。
10、VOLUME
指定由红与数据保存、备份和持久化工作的容器卷。
11、CMD
1、CMD
的作用与指令格式
指定容器启动后要干的事情。CMD
指令格式与RUN
相似,也包含两种格式:
- (1)
shell
格式:CMD <命令>
- (2)
exec
格式:CMD ["可执行文件", "参数1", "参数2" ...]
- (3)参数列表格式:
CMD ["参数1", "参数2" ...]
。在指定了ENTRYPOINT
指令后,用CMD
指定具体的参数。也就是当具有了ENTRYPOINT
后,CMD
就变成了传递参数的工具了。
注意:Dockerfile中可以由多个
CMD
指令,但是只有最后一个生效,并且CMD
会被docker run
之后的参数替换。
2、CMD
与RUN
命令的区别
(1)CMD
在docker run
时运行;
(2)RUN
在docker build
时运行。
12、ENTRYPOINT
1、ENTRYPOINT
的作用与指令格式
指定容器启动时候要运行的命令,类似于CMD
指令,但是ENTRYPOINT
不会被docker run
后面的命令覆盖,而且这些命令行参数会被当作参数传送给ENTRYPOINT
指令指定的程序。ENTRYPOINT
的指令格式如下所示:
ENTRYPOINT ["<executeable>", "<param1>", "<param2>", ...]
ENTRYPOINT
可以和CMD
一起用,通常情况下变参才会使用CMD
,这里的CMD
相当于给ENTRYPOINT
传参。
2、ENTRYPOINT
应用案例——通过Dockerfile构建nginx:test镜像
FROM nginx
ENTRYPOINT ["nginx", "-c"] #定参
CMD ["/etc/nginx/nginx.conf"] #变参
是否传参 | 按照dockerfile编写执行 | 传参运行 |
---|---|---|
Docerk命令 | docker run nginx:test | docker run nginx:test-c /etc/nginx/new.conf |
衍生出的实际命令 | nginx -c /etc/nginx/nginx.conf | nginx -c /etc/nginx/new.conf |
四、Dockerfile应用实例——以Centos为例
这里采用Dockerfile创建一个基于Centos的自定义镜像My_Centos_java8
,构建步骤如下所示:
1、制作Centos镜像需求说明
由于下载的镜像只是Centos的最小系统,甚至连最基本的vim
、ifconfig
都没有,更不用说java
了。所以这里使用dockerfile文件的构建一个具备vim+ifconfig+jdk8
的Centos7镜像。
JDK的下载镜像地址为:https://mirrors.yangxingzhen.com/jdk/,用于后面配置Centos系统的java开发环境。随便找个版本下载下来(我这里选择的是最新版本),放到本地的/liang/My_Centos_java8
文件夹中。
2、编写Dockerfile文件
在上图的/liang/My_Centos_java14
中创建Dockerfile_Centos
文件,在文件中输入如下的Dockerfile代码:
FROM centos
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#使用ADD命令将本地文件夹下的dk-8u171-linux-x64.tar.gz添加到容器中。Docker_Centos必须与安装包处于>同一个文件夹内
ADD jdk-14_linux-x64_bin.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
CMD echo $MYPATH
CMD echo "success-----------------------OK"
CMD /bin/bash
3、根据Dockerfile构建自定义的镜像
注意:执行下面指令的时候必须与上面的
Dockerfile_Centos
文件在同一个目录中!
指令格式为:
docker build -t 新镜像名字:TAG .
注意TAG
后面有个空格和一个.
。
具体到这里的命令为:
docker build -t centosjava8:v1 .