小信 2020-04-09
在Dockerfile中我们书写了一系列的内置命令,比如form workdir和add,作为Dockerfile,他远远不止提供了这么几个命令,本节咱们就将最常用的命令进行讲解。在这里强调一下,对于我们本节所学习的命令,大家脑海里有个印象就可以了。在后续我们还会通过大量的案例进行实践。首先咱们来看一个最基础的from。
from这个指令是基于基准镜像来设计的。什么叫基于基准镜像?顾名思义,我们在构建新镜像时候,你要依托于哪个原有的镜像进行扩展。比方说在这里我书写
from centos
前面的from自然是Dockerfile的命令,而后面的centos则是centos远程仓库的镜像。在制作的时候,自然基于centos:lastest,也就是最新版本来进行扩展。
但是有一些特殊的场景,假设我们并不需要任何系统,只希望从零开始构建一个镜像的话,这时在我们的文件第一行你可以书写
from scratch
代表不依赖任何基准镜像,从零开始,这种情况是非常少见的。
而下面的这个事例更说明问题
from tomcat:9.0.22-jdk8-openjdk
冒号后面是一个版本,好,这又是什么意思呢?作为from tomcat都知道这是拿tomcat镜像,后面如果增加了冒号以后,则指明我们要下载某个特定的版本。
在这里9.0.22-jdk8-openjdk就是远程仓库给我们提供了对应版本。在前面的centos这个位置上,我们没有写冒号,它默认就会给我们下载lastest最新版,这是Docker的默认规则。
对于from基准镜像来说,这里有一个建议,作为Docker来说,尽量开发的时候,基于官方提供的Base image基准镜像来进行。
因为官方提供的我们可以认为它是安全的,如果是由其他第三方所提供的,这里他做了什么手脚我们就不清楚了。
label就是说明信息,如果放在程序中就是注释了。label没有任何功能性,它的作用就是写Dockerfile里边用于说明.
label maintainer = "itlaoqi" label version = "1.0" label description = "ITLAOQI应用镜像"
比方说这里我写了三个label,第一个说明我们的作者是谁?第二个label代表了当前Dockerfile的版本号,而第三个说明了当前镜像的用途和描述。这就是label的作用。别小看label的作用,虽然它没有任何功能,但是却为我们程序维护性提供了极大的便利。试想一下,你看到一年前你自己写的,Dockerfile还能想起来它的作用吗?如果此时有这些描述信息,那是多么的方便。
workdir设置工作目录,它和我们linux的cd命令非常的相似,就是用于设置当前的工作目录,
workdir /usr/lcoal
代表的我们将当前工作目录设置为usr/local,作为这个目录如果不存在的话,默认规则workdir会对其进行创建。
workdir ./local
workdir具备了创建目录的功能,在使用的时候我的建议是workdir虽然可以像cd一样来进行相对路径的跳转,但我更加建议在使用时使用绝对路径,也就是所有路径都以斜杠开头,书写完整的地址。
add?。这个是两个命令,我放在一块来说,它们功能非常的相似,主要用于复制文件。那么大多数情况下这里出现ADD你也可以把它替换成copy。
ADD hello / #复制到根路径
这条语句的作用就是指将hello这个文件复制到我们linux的根路径下。
ADD test.tar.gz / #添加根目录并解压
同样的ADD还有一个高级的功能,就是自动解压缩,如果我们指向的是一个test.tar.gz压缩包的话,后面跟的路径,它会自动将这个文件解压缩以后放在这个目录中。
那么ADD除了复制功能以外,它比起copy还具备着去拉取远程文件的功能。这和我们在linux系统中使用的curl或者wget命令非常的相似,可以说ADD它是我们平时构建镜像时非常常用的一个命令,帮助我们将文件从物理机复制到镜像当中去。
ENV设置环境常量,什么是环境常量呢?其实非常好理解。以前我们都在做java,如果jdk要使用的话,是不是要在系统中设置一个名为java_home的这么一个环境变量,那么在docker中也有类似的设置,这里使用env再加上环境常量的名字,后面再增加具体的值就行了。
ENV JAVA_HOME /usr/local/openjdk8 RUN ${JAVA_HOME}/bin/java -jar test.jar
就拿这个例子,env Java_home后边加上这个路径说明java_home它指向了这个地址,也就是java_home就指代了后面的路径。
那么在使用时可以使用run来运行某个linux的指令,只不过在这使用${}加上我们环境常量来进行替代。它具体的作用就相当于执行了open jdk8 bin目录下的java应用,并执行了test.jar。在这儿我们又涉及到了一个新的命令run,run用于执行linux的命令,不过现在我们先不去讲它,下一节要对它进行详细的讲解。
作为env我们推荐优先去使用,因为它可以提高我们程序的维护性。
假设在dockerfile中出现了多处需要执行Java命令的地方,我们只需要设置java_home便可以进行指代。
假设未来环境发生变化,jdk被放到了其他的位置上,没有关系,只需要改这一处,所有的应用都会生效。
expose暴露容器端口expose它的作用是将我们容器内部的端口对外暴露。书写办法也非常简单,就是这个单词后边增加对应的端口号就行了。
作为expose,它的作用就是将容器内端口暴露给物理机。
来,我们看一下这张图,作为外侧的红的部分,可以认为这是我们的一台服务器物理机。而内侧我们启动了一个tomcat容器。这里如果dokcerfile中定义了expose 8080的话,就相当于在内侧的容器中对外暴露了8080端口。 同时我们在创建容器的时候。
EXPOSE 8080 docker run -p 8000:8080 tomcat
可以看到这里我做了一个-P8000:8080,它的作用是在物理机也就是外侧的地方,用8000映射到内侧的8080端口。这样内侧的服务一旦启动,在外侧我们浏览器中输入localhost:8000的话,就可以访问到内部的8080端口提供的web应用了。这便是expose的用法。
作为Dockerfile,刚才我给大家演示了最基础,也是最常见的几个指令,但是这并不能足够支撑我们构建一个镜像,因为在除了复制切换目录暴露端口之外,还有大量的Linux的命令需要执行,那该怎么做?下一节我们继续讲解。