一、是什么
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
1.构建三步骤
(1)编写Dockerfile文件
(2)使用docker build命令基于该Dockerfile中的指令构建一个新的镜像
(3)docker run命令创建容器
2.文件是什么样
以centos为例
FROM scratch
ADD centos-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="20191001"
CMD ["/bin/bash"]
其中 FROM、ADD、LABEL、CMD都是保留字指令
二、DockerFile构建过程解析
1.Dockerfile内容基础知识
(1)每条保留字指令都必须为大写字母且后面要跟随至少一个参数
(2)指令按照从上到下,顺序执行
(3)#表示注释
(4) 每条指令都会创建一个新的镜像层,并对镜像进行提交
2.Docker执行Dockerfile的大致流程
(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成
3. 总结
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
* Dockerfile是软件的原材料
* Docker镜像是软件的交付品
* Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
(1) Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者 是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系 统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
(2) Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正 开始提供服务;
(3) Docker容器,容器是直接提供服务的。
四、常用保留字指令(DSL语法)
1.FROM(指定基础image)
构建指令,必须指定且需要在Dockerfile其他指令的前面。后续的指令都依赖于该指令指定 的image。FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。 FROM命令告诉docker我们构建的镜像是以哪个(发行版)镜像为基础的。第一条指令必须是 FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指 令。
该指令有两种格式:
2.MAINTAINER(用来指定镜像创建者信息)
3.RUN(镜像构建时需要运行的命令)
构建指令,RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令。
4.CMD(设置container启动时执行的操作)
设置指令,用于container启动时指定的操作。该操作可以是执行自定义脚本,也可以是执行系统命令。该指令只能在文件中存在一次,如果有多个,则只执行最后一条。
该指令有三种格式:
5.ENTRYPOINT(设置container启动时执行的操作)
设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
6.USER(设置container容器的用户)
7.EXPOSE(指定容器需要映射到宿主机器的端口)
设置指令,该指令会将容器中的端口映射成宿主机器中的某个端口。当你需要访问容器的时候,可以不是用容器的IP地址而是使用宿主机器的IP地址和映射后的端口。
要完成整个操作需要两个步骤,首先在Dockerfile使用EXPOSE设置需要映射的容器端口,然后在运行容器的时候指定‐p选项加上EXPOSE设置的端口,这样EXPOSE设置的端口号会被随机映射成宿主机器中的一个端口号。也可以指定需要映射到宿主机器的那个端口,这时要确保宿主机器上的端口号没有被使用。
8.ENV(用于设置环境变量)
9.ADD(从src复制文件到container的dest路径)
主要用于将宿主机中的文件添加到镜像中
10.COPY (从src复制文件到container的dest路径)
COPY是ADD的一种简化版本,目的在于满足大多数人“复制文件到容器”的需求。
COPY不支持URL,也不会特别对待压缩文件。如果build 上下文件中没有指定解压的话,那么就不会自动解压,只会复制压缩文件到容器中。
11.VOLUME(指定挂载点)
设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们知道容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
解决办法:在挂载目录后多加一个--privileged=true参数即可
12.WORKDIR(指定容器的一个目录,容器启动时执行的命令会在该目录下执行,相当于设置了容器的工作目录)
13.ONBUILD(在子镜像中执行)
五、案例
制作一个tomcat7镜像
1.mkdir /mydockerfile
2.在/mydockerfile目录下touch c.txt
3.将jdk和tomcat安装的压缩包拷贝进/mydockerfile目录
4.在/mydockerfile目录下新建Dockerfile文件
FROM centos:centos6.8
MAINTAINER hl<hl@126.com>
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u141-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-7.0.70.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_141
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-7.0.70
ENV CATALINA_BASE /usr/local/apache-tomcat-7.0.70
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# CMD ["/usr/local/apache-tomcat-7.0.70/bin/catalina.sh","run"]
ENTRYPOINT /usr/local/apache-tomcat-7.0.70/bin/startup.sh&&tail -f /usr/local/apache-tomcat-7.0.70/logs/catalina.out
5.在 /mydockerfile目录下构建镜像
docker build -t mytomcat7.0 --rm=true .
构建完成
[root@java12 mydockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mytomcat7.0 latest 262714c51a4d About an hour ago 730.7 MB
6.测试
docker run -it -d -p 9090:8080 --name mytomcat7 -v /mydockerfile/tomcat7logs/:/usr/local/apache-tomcat-7.0.70/logs --privileged=true mytomcat7.0