什么是Dockerfile
Dockerfile: 用于描述镜像的生成规则,是用于构建Docker镜像的构建文件,是一系列命令和参数构成的脚本
Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在,就类似与Linux的shell脚本,只不过Dockerfile是用来构建镜像的
在上一篇docker - 关于容器数据存储使用了Dockerfile创建了数据卷
Dockerfile文件案例
可以先查看这些知名镜像的Dockerfile:
Docker官网:https://hub.docker.com/
搜索查看centos的Dockerfile
对该Dockerfile进行解释:
FROM scratch
scratch就类似与Java的object对象,这是基础镜像
该镜像是一个空的镜像,专门用于构建最小镜像,直接pull会报错,scratch是一个保留名称
ADD centos-7.7-x86_64-docker.tar.xz /
解压centos-7.7-x86_64-docker.tar.xz
并添加进本镜像
LABEL org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20191024"
label是标签,描述这个image的一些信息
CMD ["/bin/bash"]
指定容器启动后在容器内立即要执行的指令,因为有这一行,我们run运行时docker run -it centos
后会立即在容器内打开一个shell终端
Dockerfile解析过程
Dockerfile基础知识:
- 每条保留字指令必须为大写字母且后面至少要跟随一个参数
- 指令从上到下顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Dockerfile执行流程:
- dockerfile从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit提交一个新的镜像层
- docker再基于刚才提交的镜像运行一个新的容器
- 执行dockerfile的下一条指令直到所有的指令都指向完成
例如这个镜像,每完成一步,都会执行Removing intermediate container
卸下中间容器
可以理解三者的关系为:
Dockerfile是软件的原材料,镜像是软件的交付品,容器可以认为是软件的运行态
Dockerfile面向开发,Docker镜像是交付标准,Docker容器涉及部署与运维
Dockerfile保留关键字
- FROM
表示当前镜像是基于哪个镜像
base 镜像有两层含义:
不依赖其他镜像,从 scratch 构建。
其他镜像可以之为基础进行扩展。
Docker Hub中打不过镜像都是通过在base镜像中安装和配置需要的软件构建出来的
- MAINTAINER
作者的信息:作者+作者的邮箱
-
RUN
容器构建是需要运行的额外的一些命令 -
EXPOSE
当前容器对外暴露的端口号
- WORKDIR
登录后默认的工作目录,如centos的默认为根目录/
- ENV
用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest
WORKDIR $MY_PATH
-
ADD
拷贝+解压缩
在宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包 -
COPY
拷贝文件和目录到镜像
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内<目标路径>位置 -
VOLUME
设置容器数据卷 -
CMD
- 指定一个容器启动后要运行的命令
- Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run后面添加的参数替代
- ENTRYPOINT
和CMD类似,都是指定容器启动时要运行的命令,区别在run后的参数会追加,不替代
- ONBUILD
当构建一个被继承的Dockerfile时会运行命令,父镜像被子镜像继承后父镜像的onbuild会被触发
我们可以通过自制镜像来验证
自定义mycentos
DockerfileCentos:
FROM centos
MAINTAINER zfk<..>
ENV MYPATH /opt/test
WORKDIR $MYPATH
RUN yum -y install vim
EXPOSE 8088
CMD echo $MYPATH
CMD echo "sucess------------ok"
CMD /bin/bash
一层层的运行命令:
mycentos:因为下载了vim包,增加了一些大小
直接进入到我们设置的默认工作路径/opt/test
因为在我们的镜像中添加了vim,即可以使用vim命令
可以通过docker history
命令查看镜像信息
关于ONBUILD
onbuild涉及到镜像的继承关系
Dockerfile01:
FROM centos
RUN yum install -y curl
ENTRYPOINT ["curl","-s","http://ip.cn"]
ONBUILD RUN echo "this is father images onbuild"
构建镜像:
新加一个Dockerfile,基于myip_father镜像
FROM myip_father
RUN yum install -y curl
ENTRYPOINT ["curl","-s","http://ip.cn"]
构建镜像时,运行了父镜像myip_father的onbuild命令,打印this is father images onbuild
自制tomcat
自制一个基于Centos,添加jdk,tomcat,并会自运行tomcat的镜像
FROM centos
MAINTAINER zfk<..>
COPY cp.txt /usr/local/container.txt
ADD jdk1.8.0_141.tar.gz /usr/local/
ADD tomcat.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_141
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/tomcat
ENV CATALINA_BASE /usr/local/tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8088
CMD /usr/local/apache-tomcat-8.5.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.56/logs/catalina.out
运行镜像,这里设置了后台运行,映射端口为8888,设置数据卷,test为我们要放置web工程的地方,logs是日志
docker run -d -p 8888:8080 --name mycat
-v /usr/local/tomcat/test:/usr/local/apache-tomcat-8.5.56/webapps/test
-v /usr/local/tomcat/logs:/usr/local/apache-tomcat-8.5.56/logs
--privileged=true mytomcat
运行成功后,可以通过8888端口访问:
container是COPY命令复制的,apache-tomcat-8.5.56即tomcat解压目录
我们可以进入测试web项目:docker exec -it e0cdd2ecc4c6 /bin/bash
可以在宿主机往其中放入一个html
因为数据卷的原因,webapps内也存在index.html
在图形化界面验证:确实进入了