一、dockerFile是什么
1、概念: Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
2、构建三步骤:
① 编写Dockerfile文件
② docker build
③ docker run
3、文件什么样???
以我们熟悉的CentOS为例
image.png
ps:其中的 scratch 相当于java中的Object类,是所有镜像的源头。MAINTAINER 为作者的意思;LABEL标签,为说明的意思 ;CMD代表命令的意思

二、DockerFile的解析过程
1、Dockerfile内容基础知识
① 每条保留字指令都必须为大写字母且后面要跟随至少一个参数

② 指令按照从上到下,顺序执行

③ #表示注释

④ 每条指令都会创建一个新的镜像层,并对镜像进行提交

2、Docker执行Dockerfile的大致流程
① docker从基础镜像运行一个容器

② 执行一条指令并对容器作出修改

③ 执行类似docker commit的操作提交一个新的镜像层

④ docker再基于刚提交的镜像运行一个新容器

⑤ 执行dockerfile中的下一条指令直到所有指令都执行完成

总结:
image.png
image.png

三、DockerFile体系结构(保留字指令)
image.png

1、FROM
作用:基础镜像,当前新镜像是基于哪个镜像的

2、MAINTAINER
作用:镜像维护者的姓名和邮箱地址

3、RUN
作用:容器构建时需要运行的命令

4、EXPOSE
作用:当前容器对外暴露出的端口

5、WORKDIR
作用:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

6、ENV
作用:用来在构建镜像过程中设置环境变量
image.png
WORKDIR $MY_PATH ,就相当于设置了登录目录为 /usr/mytest

7、ADD
作用:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

8、COPY
作用:类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
写法:
① COPY src dest
② COPY [“src”, “dest”]

9、VOLUME
作用:容器数据卷,用于数据保存和持久化工作

10、CMD
作用:指定一个容器启动时要运行的命令
注意:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换

11、ENTRYPOINT
作用:指定一个容器启动时要运行的命令
注意:ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,但是不会被 docker run 之后的参数替换,它为追加

12、ONBUILD
作用:当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发

总结:
image.png

四、案例
1、Base镜像(scratch)
Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的

2、自定义镜像mycentos
a). 编写
① Hub默认CentOS镜像什么情况
image.png
② 准备编写DockerFile文件
#引用我们从官网上下载的centos镜像作为基础镜像
FROM centos

定义作者
MAINTAINER spz584289580@qq.com

定义环境变量
ENV MYPATH /usr/local

引用定义的环境变量,定义登录后的落脚点
WORKDIR $MYPATH

因为基础镜像没有vim 和 ifconfig,下面两句为执行yum命令下载相关插件
RUN yum -y install vim
RUN yum -y install net-tools

对外暴露端口号为80
EXPOSE 80

打印
CMD echo $MYPATH
CMD echo “success———————ok”

执行 /bin/bash
CMD /bin/bash

b). 编写
docker build -t 新镜像名字:TAG .
会看到 docker build 命令最后有一个 .
. 表示当前目录
docker build -f /mydocker/Dockerfile2 -t mycentos:1.3 .
执行完之后如下图所示
image.png
image.png
c). 运行
docker run -it 新镜像名字:TAG
docker run -it mycentos:1.3
image.png
运行好之后,我们可以看到我们进入mycentos的落脚点为我们在dockerfile中配置的 /usr/local
我们再试试vim 和 ifconfig是否安装成功

image.png
image.png
image.png
image.png
通过上面几张图片可以看到,我们自定义的centos 中,vim命令和ifconfig命令都可以正常运行了

d). 列出镜像的变更历史
docker history 镜像名
image.png

3、CMD/ENTRYPOINT 镜像案例
该两个命令,都是指定一个容器启动时要运行的命令
a). CMD
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
例如:我们正常运行一个tomcat时,我们可以看到会打印很多启动日志
docker run -it -p 8888:8080 tomcat
image.png
是因为在tomcat的dockerfile中,最后一句是如下命令
image.png
如果,我们在正常启动的命令后追加 ls -l 命令会怎么样
docker run -it -p 8888:8080 tomcat ls -l
image.png
我们看到执行完命令之后打印了容器里面的目录,但是我们的tomcat容器并没有启动,那是因为我们追加的参数,把docfile中的最后一句命令给覆盖了,
所以我们就只看到了我们追加的打印目录命令起效了。

b). ENTRYPOINT
解释:docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
① curl 命令解释:
curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。
如果系统没有curl可以使用yum install curl安装,也可以下载安装。
curl是将下载文件输出到stdout

使用命令:curl http://www.baidu.com
执行后,www.baidu.com的html就会显示在屏幕上了

这是最简单的使用方法。用这个命令获得了http://curl.haxx.se指向的页面,同样,如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。 如果下载的是HTML文档,那么缺省的将只显示文件头部,即HTML文档的header。要全部显示,请加参数 -i
image.png
② 案例case:
制作CMD版可以查询IP信息的容器
FROM centos
RUN yum install -y curl
CMD [ “curl”, “-s”, “http://ip.cn“ ]

创建dockerfile3
image.png
build dockerfile3
docker build -f /mydocker/Dockerfile3 -t myip .

image.png
image.png
如果我们希望显示 HTTP 头信息,就需要加上 -i 参数
image.png
我们看到 如果用cmd 加的命令 后面加-i就会报错,那为什么呢?
我们可以看到可执行文件找不到的报错,executable file not found。
之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。
因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。

那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:

$ docker run myip curl -s http://ip.cn -i

制作ENTROYPOINT版查询IP信息的容器

FROM centos
RUN yum install -y curl
ENTRYPOINT [ “curl”, “-s”, “http://ip.cn“ ]
image.png
如图可见使用了ENTRYPOINT 后-i参数就追加到我们预先设置好的参数列表中,并且按照我们想要的效果打印出报文头

4、ONBUILD 案例
作用当该镜像被子镜像继承时,父镜像的ONBUILD 被触发
① 创建Dockerfile4
image.png

image.png
② 创建 Dockerfile5
image.png
这个dockerfile5继承了父类中有ONBUILD 的镜像,构建时就会触发父类的ONBUILD ,如下图所示就是触发的打印出的语句
image.png

5、自定义镜像Tomcat9
① mkdir -p /spzuse/mydockerfile/tomcat9
image.png
② 在上述目录下touch c.txt
image.png
③ 将jdk和tomcat安装的压缩包拷贝进上一步目录 apache-tomcat-9.0.10.tar.gz、jdk-8u161-linux-x64.tar.gz
apache-tomcat-9.0.10.tar.gz
image.png
④ 在/spzuse/mydockerfile/tomcat9目录下新建Dockerfile文件

  1. FROM centos
  2. MAINTAINER spz<584289580@qq.com>
  3. #把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
  4. COPY c.txt /usr/local/cincontainer.txt
  5. #把java与tomcat添加到容器中
  6. ADD jdk-8u161-linux-x64.tar.gz /usr/local/
  7. ADD apache-tomcat-9.0.10.tar.gz /usr/local/
  8. #安装vim编辑器
  9. RUN yum -y install vim
  10. #设置工作访问时候的WORKDIR路径,登录落脚点
  11. ENV MYPATH /usr/local
  12. WORKDIR $MYPATH
  13. #配置java与tomcat环境变量
  14. ENV JAVA_HOME /usr/local/jdk1.8.0_161
  15. ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  16. ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.10
  17. ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.10
  18. ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
  19. #容器运行时监听的端口
  20. EXPOSE 8080
  21. #启动时运行tomcat
  22. # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.10/bin/startup.sh" ]
  23. # CMD ["/usr/local/apache-tomcat-9.0.10/bin/catalina.sh","run"]
  24. CMD /usr/local/apache-tomcat-9.0.10/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.10/bin/logs/catalina.out

⑤ 构建
docker build -t spztomcat9
注意:我之前构建命名为 docker build -f /mydocker/Dockerfile3 -t myip . 其中 -f 是指定目录下的dockerfile ,若不填-f 则默认为当前目录下命名为Dockerfile的文件
image.png
⑥ run

  1. #以守护进程的形式后台运行,宿主机端口9080映射容器端口8080 ,命名为myt9
  2. docker run -d -p 9080:8080 --name myt9
  3. #多对多创建数据卷:第一个方便部署项目,第二个方便查看日志
  4. -v /spzuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.10/webapps/test
  5. -v /spzuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.10/logs
  6. #如果你的写权限不够的话把这个设置为true
  7. --privileged=true
  8. spztomcat9

image.png
image.png
docker exec fdaeecae2a9d ls -l ,通过该命令我们看到,我们dockerfile中 ADD的 两个压缩包也加入并解压了,COPY的文件也在
image.png
查看我们之前设置的java
image.png

6、结合前述的容器卷将测试的web服务test发布
在我们宿主机的/spzuse/mydockerfile/tomcat9/test目录下建立一个简单的web项目,因为这是之前建立的容器卷项目,所以他会被同步到我们的容器中
image.png
a.jsp

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  6. <title>Insert title here</title>
  7. </head>
  8. <body>
  9. -----------welcome------------
  10. <%="i am in docker tomcat self "%>
  11. <br>
  12. <br>
  13. <% System.out.println("=============docker tomcat self");%>
  14. </body>
  15. </html>

image.png

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  5. id="WebApp_ID" version="2.5">
  6. <display-name>test</display-name>
  7. </web-app>

image.png

我们重启容器,然后访问a.jsp
image.png
我们看到我们的页面已经启动起来了
然后我们在不关闭服务的情况下修改该页面

image.png
我们刷新页面,看到我们的修改被更新了,通过容器卷我们就可以这样修改容器中的项目,非常方便
image.png
我们看看跟日志关联的/spzuse/mydockerfile/tomcat9/tomcat9logs/宿主机目录
image.png
我们看到在我们宿主机上就已经有相关日志信息了 ,cat catalina.out查看我们之前所写的后台打印是否打印成功
image.png
后台日志也打印成功

五、小总结
image.png