Docker——Dockerfile的理解 & 案例实操

简介: Docker——Dockerfile的理解 & 案例实操

文章目录:


1.Dockerfile是什么?

2.Dockerfile体系结构

3.案例实操

3.1 案例一(FROMMAINTAINERRUNEXPOSEWORKDIRENVCMD

3.2 案例二(CMDENTRYPOINT

3.3 案例三(ONBUILD

3.4 案例四(自定义tomcat9镜像)

4.小总结



1.Dockerfile是什么?


Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。

整个Docker镜像的构建过程是:编写Dockerfile文件 → docker build → docker run

Dockerfile文件的具体内容,我们以centos镜像为例,链接:https://github.com/CentOS/sig-cloud-instance-images/blob/b2d195220e1c5b181427c3172829c23ab9cd27eb/docker/Dockerfile

Dockerfile内容的基础知识:

·       每条保留字指令都必须为大写字母且后面要跟随至少一个参数。

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

·       #表示注释。

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

Docker执行Dockerfile的具体流程:

·       docker从基础镜像运行一个容器。

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

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

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

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



从应用软件的角度来看,DockerfileDocker镜像与Docker容器分别代表软件的三个不同阶段,

·       Dockerfile是软件的原材料。

·       Docker镜像是软件的交付品。

·       Docker容器则可以认为是软件的运行态。

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

1. Dockerfile,需要定义一个DockerfileDockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;

2. Docker
镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;

3. Docker
容器,容器是直接提供服务的。


2.Dockerfile体系结构



·       FROM——基础镜像,当前新镜像是基于哪个镜像的

·       MAINTAINER——锐像维护者的姓名和邮箱地址

·       RUN—容器构建时需要运行的命令

·       EXPOSE ——当前容器对外暴露出的端口

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

·       ENV——用来在构建镜像过程中设置环境变量(ENV MY_PATH /usr/mytest    WORKDIR $MY_PATH

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

·       COPY——类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置

·       VOLUME——容器数据卷,用于数据保存和持久化工作

·       CMD——指定一个容器启动时要运行的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换

·       ENTRYPOINT——指定一个容器启动时要运行的命令。ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数

·       ONBUILD——当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发


3.案例实操


3.1 案例一(FROM、MAINTAINER、RUN、EXPOSE、WORKDIR、ENV、CMD)

首先,我这里先run一个centos镜像,以它为模板创建一个centos容器实例运行。

但是运行进入docker中的centos终端之后,发现之前在linux中常用的vimifconfig这些命令都用不了,此时pwd位于根目录下。


我这里要做的修改是使得vimifocnfig这两个命令在dockercentos容器中生效,同时当我进入这个容器时,不再位于根目录/下,而是直接到达/usr/local目录下

这就需要创建新的Dockerfile文件,之后build出一个新的镜像,最后run运行。


上面是Dockerfile文件的内容,创建完之后,下面执行docker build,以Dockerfile2文件构建出一个新的自定义的centos镜像。

构建成功,可以docker images查看一下。


三步走(编写Dockerfile → docker build → docker run),我们已经走完了前两步,最后就可以run了。

可以看到以我们刚刚新构建的镜像为模板生产出一个自定义的centos容器实例,进入之后,pwd看到当前工作目录为 /usr/local,同时,vim可以正常的编写文件,ifconfig也可以查出ip、网卡等相关信息。


这里还可以使用docker history可以查看该容器的构建过程、变更历史。


3.2 案例二(CMD、ENTRYPOINT)


首先,我们看一下tomcat官方镜像的Dockerfile文件,链接:https://github.com/docker-library/tomcat/blob/fb2ffad09f315bde50308816f7d84897b856e164/9.0/jdk8/corretto/Dockerfile

可以看到这个Dockerfile文件的最后一行是

CMD ["catalina.sh", "run"]

而我这里docker run这个tomcat,在命令的最后添加一个ls -l,那么此时就相当于在这个tomcatDockerfile文件的最后一行添加了 CMD ls -l,此时变成了

  CMD ["catalina.sh", "run"]
  CMD ls -l

由于Dockerfile文件中关于RUN的定义是:CMD——指定一个容器启动时要运行的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。

所以下面的截图中,我这样去runls -l顺利的查出了/usr/local/tomcat目录下的内容。但是docker ps却显示当前并没有容器实例在运行,这就说明它的Dockerfile文件的倒数第二行的 CMD ["catalina.sh", "run"] 已经被 CMD ls -l 覆盖了。


上面演示了Dockerfile文件中如果存在多个CMD了话,那么只有最后一个CMD生效。


下面再来说说和CMD很像的ENTRYPOINTENTRYPOINT——指定一个容器启动时要运行的命令。ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。


ENTRYPOINT并不会像CMD那样覆盖前面的命令参数,而是会追加,如果有一个ENTRYPOINT就正常执行,如果有第二个ENTRYPOINT就追加到第一个的后面,一同执行。


curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有curl可以使用yum install curl安装,也可以下载安装。curl是将下载文件输出到stdout



3.3 案例三(ONBUILD)

ONBUILD——当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发。

这里首先创建一个Dockerfile3文件,然后以centos为基础镜像构建一个自定义的新镜像myip_father,然后再创建一个Dockerfile4文件,这里就不再以centos为基础镜像了,也就不再是FROM centos,而是FROM myip_father,即此时镜像myip_son继承了myip_father

最后当我docker build构建这个子镜像myip_son的时候,可以看到父镜像中ONBUILD后面的 RUN echo "father onbuild-------666" 这句话被打印出来了。



3.4 案例四(自定义tomcat9镜像)

上面已经介绍了很多Dockerfile中的命令,还差ADDCOPY,这两个在此案例中讲解。


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


COPY——类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置。


说的明白点:比如我们在淘宝买东西,最终肯定是以快递的方式送达,ADD就是指快递员给你送货到家之后,他帮你把快递拆开;COPY则是指快递员给你送货到家之后,他不会拆封,由你自己来拆封。


因为我们要自定义tomcat9,所以就需要两个压缩包(tomcatjdk),我这里先级联创建了一个测试目录,然后将压缩包拷贝过来用作测试(先不解压)。


要构建新的tomcat镜像,第一步必然是编写Dockerfile文件。

FROM centos
MAINTAINER szh<2656307671@qq.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u121-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.13.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_121
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.13
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.13
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE  8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.13/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.13/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.13/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.13/bin/logs/catalina.out


此时当前目录下有两个压缩包、c.txtDockerfile文件,先说明一下,这两个压缩包后面对应的就是ADD命令,因为ADD会在拷贝压缩包的同时帮你解压;c.txt文件对应的是COPY命令,只是单纯的拷贝。

然后我们docker build以此Dockerfile文件来构建自定义的tomcat9镜像。


构建完成之后,可以docker images查看一下。

下面的docker run命令:

·       -d是以守护式容器的方式启动,即后台启动(-it则是交互式容器,即前台启动)

·       -p指定docker中映射tomcat的端口为1234

·       --name对以此镜像生产的容器实例重命名

·       -v则是在容器中添加数据卷(以实现宿主机和docker容器之间的数据持久化 + 数据共享)

·       这里只所以可以写多个-v,在容器中添加多个数据卷,就依赖于后面的--privileged=true

·       最后的szh-tomcat9是我们要以哪个镜像为模板生产容器实例运行

run之后,可以docker ps查看一下当前运行的容器实例。


 此时,到浏览器中,虚拟机ip + -p中映射的端口号即可访问tomcat的主页。


由于我们docker run -d是后台启动,并不像docker run -it前台启动那样直接进入tomcat的目录下。

所以这里可以使用docker exec命令进入正在运行的某个容器实例,后面添加了 ls -l,就覆盖了上一个CMD


下面,我们可以尝试着在docker中的这个tomcat容器中部署一个简单的web服务,对应test目录。

WEB-INF目录下,创建web服务所需的web.xml,在标签中声明该web服务对外的名称为test


退出WEB-INF目录,创建一个a.jsp的简单页面。

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


因为我们在这个tomcat容器中添加了部分文件,所以这里需要docker restart重启一下这个容器。


重启之后,到浏览器中,访问刚刚标签对应的web服务的别名,即/test/a.jsp

可以看到前台打出了 -----------welcome------------
                                <%="i am in docker tomcat self "%>
信息。

而后台打印的信息则是在下面截图中的路径下,<% System.out.println("=============docker tomcat self");%>



4.小总结


相关文章
|
1月前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
470 11
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
17天前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
36 9
|
17天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
50 7
|
1月前
|
应用服务中间件 PHP nginx
Docker-compose 编排lnmp(dockerfile) 完成Wordpress
通过使用Docker Compose,我们可以轻松编排LNMP环境并部署WordPress。本文详细介绍了各组件的Dockerfile和配置文件编写,并通过docker-compose.yml文件实现了整个环境的自动化部署。这种方法不仅简化了部署过程,还提高了环境的可移植性和一致性。希望本文能帮助你更好地理解和使用Docker Compose来管理和部署复杂的应用程序。
90 3
|
2月前
|
Docker 容器
docker中使用Dockerfile自动创建数据卷
【10月更文挑战第12天】
28 5
|
2月前
|
消息中间件 NoSQL Kafka
Flink-10 Flink Java 3分钟上手 Docker容器化部署 JobManager TaskManager Kafka Redis Dockerfile docker-compose
Flink-10 Flink Java 3分钟上手 Docker容器化部署 JobManager TaskManager Kafka Redis Dockerfile docker-compose
65 4
|
3月前
|
应用服务中间件 nginx Docker
Docker镜像-基于DockerFile制作编译版nginx镜像
这篇文章介绍了如何基于Dockerfile制作一个编译版的nginx镜像,并提供了详细的步骤和命令。
531 17
Docker镜像-基于DockerFile制作编译版nginx镜像
|
3月前
|
Linux Docker Windows
Docker配置https证书案例
本文介绍了如何为Docker的Harbor服务配置HTTPS证书,包括安装Docker和Harbor、修改配置文件以使用证书、生成自签名证书、配置证书以及验证配置的步骤。
203 2
Docker配置https证书案例
|
3月前
|
Ubuntu Linux Docker
Ubuntu 18.04 安装Docker实战案例
关于如何在Ubuntu 18.04系统上安装Docker的实战案例,包括安装步骤、配置镜像加速以及下载和运行Docker镜像的过程。
448 3
Ubuntu 18.04 安装Docker实战案例
|
3月前
|
应用服务中间件 Linux nginx
Docker镜像-基于DockerFile制作yum版nginx镜像
本文介绍了如何使用Dockerfile制作一个基于CentOS 7.6.1810的yum版nginx镜像,并提供了详细的步骤和命令。
158 20