怎么来的
dockerfile是构建镜像文件,由一系列命令和脚本参数组成,可以看成是镜像创建的源码。
任何一个docker镜像,从官网中都能对应的原生dockerfile内容,例如nginx,centos
每当dockerfile编写完毕之后,我们可以用它来构建镜像,然后使用镜像创建容器,容器初始化环境,运行命令都可以在dockerfile中指定。
在编写一个dockerfile时,我们需要使用非常多的dockerfile指令。
如mysql的dockerfile:
FROM debian:buster-slim
ENV GOSU_WERSION 1.12
RUN mkdir /docker-entrypoint-initdb.d
VOLIME /var/lib/mysql
定义当前dockerfile基础镜像,镜像创建出来基于哪个镜像实现的,每个dockerfile编辑时,必须包含这个指令,否则无法创建镜像文件
官方dockerhub库中,发现scratch是绝大部分使用镜像的最终父镜像。
FROM指令的编辑
利用文件构建一个镜像
编辑一个文件名称dockerfile-demo1
FROM centos:centos7
实际上创建出来的就是centos:centos7镜像
docker build -f dockerfile-demo1 -t centos:pcy .
在镜像的元数据中提供一个维护人的信息,可以跟随一个字符串实现
docker build -f file01 -t centos:pcy01 .
我们在构建镜像时,会有三层
维护人会写入镜像的元数据中,可以在构建完镜像,提供元数据查看
元数据查看
docker inspect 镜像id
当一个dockerfile中存在多个MAINTAINER指令时,后面的会把前面的覆盖掉。最终元数据只记录一个人
作用:在生成镜像的时候,对镜像差生一些描述信息,比如版本,创建时间,证书,作用。比如从centos:centos7官方dockerfile中可以看到LABLE标签
\表示换行下一个输入的信息,信息格式是Key-value
value一般都是一个字符串
docker build -t centos:pcy3 .
ADD指令是将宿主机中准备的文件,比如java,tar文件,在构建镜像时添加到镜像中。宿主机的文件中所在目录就是之前调用Build命令最后的.,.表示所有构建镜像需要用到的文件,都在相对路径当前目录下,也可以替换成其它位置,如果当前位置有dockerfile名称文件,-f可以省略。
将宿主机的文件放到镜像,但是以拷贝的方式,而且不会对压缩包进行解压。
设置镜像中的环境变量
比如jdk,java的环境JAVA_HOME
相当于在环境中设置了一个环境变量,赋值name=wangcuihua
启动一个容器来测试环境变量
docker run -it --name demo03 centos:xiaolaoshi03 /bin/bash
env# 查看环境变量是否配置成功
echo $name# 查看环境变量
我们想要构建自己功能的镜像,RUN比较重要。
RUN主要作用是在构建镜像的时候build,执行我们定义的命令。RUN指令在当前镜像的顶层上新建层执行命令,同时commit提交执行结果(相当于我们启动一个容器执行命令)。
RUN指令会打印三个环境变量
tomcat官方镜像中可以看到ENV使用
shell和exec区别
底层机制有所区分
shellRUN命令,会默认调用/bin/bash -c来解析命令
RUN ls /实际上执行相当于/bin/bash -c “ls /”
exec 格式,则不是使用/bin/bash -c来解析直接调用。当前的镜像内部有什么默认解析进程,就用什么解析进程。
如果命令中使用环境变量就不会解析
如果想要解析,修改dockerfile
注:
shell命令必须具备解析环境,并不是所有的解析都具备解析环境。
exec可以根据镜像的环境选择不同的形式运行命令,而且这种格式能够在有些条件下避免命令的混淆
我们在dockerfile中定义镜像创建环境变量,使用指令ENV,容器启动时,我们可以用run命令的-e选项来设置相关的内容
docker run -it -e "name=liuxiaolan" centos:pcy8 /bin/bash
# -e可以配置环境变量
启动的容器以及把容器中的环境给替换了,但是-e选项不会把dockerfile里面的内容给替换,也就是当前容器的环境变量变化,但是里面的镜像不变
环境变量使用流程图
先得构建一个镜像,然后再利用这个镜像创建容器
WORKDIR表示当前工作目录,如果不指定,默认工作目录时/。在镜像中指定了WORKDIR,我们使用镜像创建容器,进入容器的默认路径也是这个工作目录。
例如tomcat最终的启动容器要运行命令是catalina.sh start,但是这个目录所在目录时tomcat/bin所以镜像会设置WORKDIR在当前这个bin文件夹下,启动catalina.sh start运行。
案例:
数据卷的意思,用来创建镜像的同时,创建挂载点,这样使用这个镜像启动的容器会有匿名挂载的数据卷。
创建默认挂载点
运行构建的dockerfile之后,创建镜像,查看匿名数据卷
查看元数据
docker inspect bdaddd07789e
当我们在运行这个容器的时候,容器在运行某个服务的时候,比如tomcat,nginx这种http服务,需要外界访问这个服务,那么要让容器暴露端口出来,否则无法北宿主机的端口绑定。
都是在镜像运行容器时,执行的命令,格式分为shell和exec的形式
实现一个容器启动时,运行ls命令
和RUN指令格式类似,
CMD细节
最多只在dockerfile编写一次,如果编写多次,后面的把前面的覆盖,只运行最后一个CMD
这个指令和CMD类似
同样也支持exec形式
如果定义多个ENTRYPOINT也和CMD相同,会被覆盖掉
准备一个配置文件Dockerfile
多种情况:
https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact