Dockerfile
是什么
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
构建三步骤
- 编写Dockerfile文件
- docker build
- docker run
Dockerfile构建过程解析
Dockerfile内容基础常识
- 每条指令都必须为大写字母且后面要跟随至少一个参数,例如FROM scratch(这里的scratch就类似于java中的父类object)
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交(每个镜像都是一个花卷,镜像ID显示的是最外层的ID)
Docker执行Dockerfile的大致流程
- docker从基础镜像中运行一个容器
- 执行一条指令并对容器做出修改(自动)
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新的容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
小总结
Dockerfile体系结构(这里写的时保留字指令)
- FROM +基础镜像,表示当前镜像是基于哪个镜像的,比如FROM scratch
- MATAINER +镜像维护者的姓名和邮箱地址(这个不用了已经,现在用LABEL ,比如LABEL author=leifan)
- RUN + 容器构建时需要执行的命令,就类似于我们执行代码过程中的sout输出语句
- EXPOSE + 暴露出当前容器对外的端口号
- WORKDIR + 指定在创建容器后,终端默认登录进来的工作目录,一般我们创建容器后都是进去根目录
- ENV + 用来构建镜像过程中设置环境变量,例如ENV MY_PATH /user/mytest,就表示在后续的指令中,都可以通过MY_PATH代表/user/mytest这个路径
- ADD(COPY+解压缩) + 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
- COPY + 类似ADD,拷贝文件和目录进镜像,将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<>目标路径>位置,但是不会解压缩和处理URL
- VOLUME + 容器数据卷, 用于数据保存和持久化工作
- CMD + 指定一个容器启动时要运行的命令,Dockerfile可以有多个CMD指令,但最后只有最后一个生效,CMD会被docker run之后的参数替换,比如docker run -it centos /bin/bash,此时不论CMD的参数是啥,都只会执行/bin/bash命令
- ENTRYPOINT + 指定一个容器启动时要运行的命令,ENTRYPOINT的目的和RUN一样,都是在指定容器启动程序及参数,它和RUN的区别是它不会被docker run之后的参数替换,它是追加
- ONBUILD + 当构建一个被继承的Dockerfile时会运行这个命令,父镜像在被子镜像继承后,父镜像的ONBUILD被触发,可以用来让父镜像做一些收尾的工作
小总结
案例
Base镜像scratch: Docker hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的
自定义镜像mycentos
- 编写
- Hub默认centos镜像的情况 (我们启动容器后默认路径是根目录/bin/bash,而且不支持vim和ifconfig这些东西,现在我想让它支持这些东西)
- 编写Dockerfile文件
- 在虚拟机中的mycentos目录下进行编译,我这里截图只看命令就成,在根目录下会报错的.
- 我们此时启动一个mycentos容器,我们就会发现我们当前位置就是MYPATH(我这里的时/mycentos/user)路径下
- 列出镜像的变更历史(在虚拟机下,不是在容器内哈): docker history 镜像名,注意它是倒着执行的,类似于压栈过程
- Hub默认centos镜像的情况 (我们启动容器后默认路径是根目录/bin/bash,而且不支持vim和ifconfig这些东西,现在我想让它支持这些东西)
CMD/ENTRYPOINT镜像案例
都是指定一个容器启动时要运行的命令
- CMD: Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run指令在镜像名/镜像ID之后的参数替换,也就是说会执行镜像ID之后的参数而不会去执行镜像的Dockerfile中本来的参数
- ENTRYPOINT: docker run 之后的参数会被当做参数传递给ENTRYPOINT,将参数放在其之后形成新的命令组合
- 制作CMD版可以查询IP信息的容器(这里要用到curl指令,它是用来向指定地址的html)
- 编辑Dockerfile3(其中ip.cn是查ip的网址)
- 在Dockerfile3所在的文件夹目录下build形成一个新的镜像: docker build -f /mydocker/Dockerfile3 -t myip .
- 直接运行myip容器就可以看到当前ip的信息了: docker run -it myip
- 制作CMD版可以查询IP信息的容器(这里要用到curl指令,它是用来向指定地址的html)
ONBUILD案例(改造上述的查询ip的容器)
ONBUILD指令说白了就是当有这个语句的Dockerfile文件build成的镜像A被其他镜像B继承了之后,B镜像生成的过程中就会输出A中的ONBUILD的语句
- 修改Dockerfile4文件内容
- 重新build生成myip_parent镜像(这里要注意命令一定要在Dockerfile所在的文件夹目录中执行,其他地方执行会报错的)
- 创建Dockerfile5,修改FROM的参数为myip_parent
- build新镜像myip_inherited,观察输出语句