什么是DockerFile:
用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
构建Dockerfile的三个步骤:
- 编写Dockerfile文件
- docker build
- docker run
dockerfile构建过程解析:
dockerfile内容基础知识:
- 每条保留字指令都必须是大写字母,且后至少跟一个参数
- 指令按照从上到下逐条执行
#
注释- 每条指令都会创建一个新的镜像层,并对镜像进行提交
docker执行dockerfile的大致流程:
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 提交生成一个新的镜像层
- 基于新生成的镜像运行一个容器
- 执行dockerfile中的下一条指令,指导所有的指令都执行完成
dockerfile体系结构(保留字指令):
- FROM:基础镜像,即当前镜像是基于哪个镜像的(类似于继承,当前类的父类是谁)。
- MAINTAINER:镜像维护者的姓名和邮箱地址。
- RUN:容器构建时要运行的命令。
- EXPOSE:当前容器对外暴露出的端口号。
- WORKDIR:指定在创建容器后,终端默认登陆进来的工作目录,一个落脚点。
- ENV:用来在构建镜像过程中设置环境变量。见 ①
- ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包。
- COPY:类似于ADD,拷贝文件和目录到镜像。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置;
两种写法:
1、copy xxx yyy
2、COPY['xxx','yyy']
- VOLUME:容器数据卷,用于数据保存和持久化工作
- CMD:指定一个容器启动时要运行的命令,见 ②
dockerfile文件中可以存在多个CMD命令,但只有最后一个生效,CMD后被docker run之后的参数替换。 - ENTRYPOINT:指定一个容器启动时要运行的命令。
ENTRYPOINT和CMD的目的一样,都是在指定容器启动程序及参数(不会被覆盖)。 - ONBUILD:当构建一个被继承的dockerfile时运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发。
① ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前指定了环境变量前缀一样。也可以在其他指令中直接使用这些环境变量。
如:WORKDIR $MY_PATH
② CMD 容器启动命令
CMD指令的格式和 RUN 相似,也是两种格式:
1、shell格式:CMD <命令>
2、exec格式:CMD[“可执行文件”,“参数1”,“参数2”,…]
3、参数列表格式: CMD[“参数1”,“参数2”,…],在指定了ENTRYPOINT指令后,用CMD指令的具体参数。
保留字指令的案例:
base镜像(scratch):Docker Hub中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建处理的。
自定义镜像没有一些命令(centos为例)
- 停止当前镜像的运行,编写dockerfile文件(之前创建过mydocker目录,就直接在里边创建文件了)
# 基础镜像,基于centos
FROM centos
# 设置维护者的姓名、邮箱地址
MAINTAINER leyton<leyton01@protonmail.com>
# 配置环境变量
ENV MY_PATH /usr/local
# 设置默认的工作目录
WORKDIR $MY_PATH
# 执行两条安装语句来安装vim、net-tools
RUN yum -y install vim
RUN yum -y install net-tools
# 暴露端口
EXPOSE 80
# 容器启动时运行的命令
CMD echo $MY_PATH
CMD echo "success............ok"
CMD /bin/bash
2. 构建新的镜像(build)
命令:docker build -f /mydocker/DockerFile2 -t 新镜像名称:TAG .
docker build -f /mydocker/DockerFile2 -t mycentos:1.3 .
别忘了最后的点(点表示当前目录)
…
- 运行mycentos:1.3镜像,看一下工作目录是否是设置的环境变量/usr/local,是否可以使用vim以及ifconfig命令
- 列出镜像的变更历史
docker history 镜像ID
案例(续):
此案例主要针对CMD、ENTRYPOINT
两个都是在容器启动时要运行的命令
CMD :docker run 之后会覆盖前边的CMD命令,只有最后一个生效
如运行tomcat
docker run -it tomcat
运行tomcat 改变最后的语句
docker run -it tomcat ls -l
上面一句话相当于Dockerfile中在最后添加CMD ls -l,覆盖上边的CMD /bin/bash
ENTRYPOINT:docker run之后的参数会被当做参数传递给ENTRYPOINT,之后形成新的命令组合
编写dockerfile文件:
FROM centos
RUN yum -y install curl
CMD [‘curl’, ‘-s’, ‘http://ip.cn’]
什么是curl:
build
docker build -f /mydocker/DockerFile3 -t myip .
别忘了最后的点
运行一下:
如果现实数据头headers
curl -s -i http://ip.cn
但是写好的dockerfile能不能这样运行呢?显然不能
dockerfile里是CMD [‘curl’, ‘-s’, ‘http://ip.cn’],而运行的那句话相当于CMD -i
把上一句给覆盖掉了,显然是不行的。
此时可以考虑用ENTRYPOINT
编写dockerfile文件:
FROM centos
RUN yum -y install curl
ENTRYPOINT [‘curl’, ‘-s’, ‘http://ip.cn’]
此时运行命令加上 -i 的参数相当于 [‘curl’, ‘-s’, ‘-i’, ‘http://ip.cn’],不会把之前的覆盖掉
案例(续):ONBUILD
编写Dockerfile4文件(作为父镜像的文件)
FROM centos
RUN yum -y install curl
ENTRYPOINT [“curl”, “-s”, “https://ip.cn”]
ONBUILD RUN echo ‘father image onbuild…’
生成镜像myip_father
docker build -f /mydocker/Dockerfile4 -t myip_father .
别忘了最后的点
编写Dockerfile5文件(作为子镜像的文件,继承Dockerfile4)
FROM myip_father
RUN yum -y install curl
ENTRYPOINT [“curl”, “-s”, “https://ip.cn”]
生成镜像myip_son
docker build -f /mydocker/Dockerfile5 -t myip_father .
别忘了最后的点
此时父镜像会执行ONBUILD
生成myip_father镜像的图:
生成myip_son镜像的图: