六、Dockerfile解析
分别准备好两个已经写好的.net 程序与springboot程序, 如何让这两个程序在docker 中运行呢?
1. 什么是Dockerfile
Dockerfile 是用来构建Docker镜像的构建文件 ,是由一系列命令和参数构成的脚本。
构造三个步骤
-
1.编写Dockerfile文件
-
2.编译:docker build
-
3.生成容器:docker run ....
2. 基础知识
-
1.每条保留字指令都必须为大写字母且后面要跟随至少一个参数
-
2.指令按照从上到下,顺序执行
-
3.# 表示注释
-
4.每条指令都会创建一个新的镜像层并对镜像进行提交
从软件开发的角度来说,可以分为三个层次:
Dockerfile --------> 产品原型
镜像文件 ---------> UI设计图
运行的容器 ---------> 最终交付的成品
3.Dockerfile体系结构(保留字指令)
FROM :基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER:镜像维护者的姓名和邮箱地址
RUN:容器构建时需要运行的命令(使用&&连接多条命令,不建议使用多个RUN指令,因为会造成镜像层太多)
FROM centos:6.9 MAINTAINER 任我行码农场 RUN sed -i "s|enabled=1|enabled=0|g" /etc/yum/pluginconf.d/fastestmirror.conf && curl -o /etc/yum.repos.d/CentOS-Base.repo https://www.xmpan.com/Centos-6-Vault-Aliyun.repo && yum -y install vim
EXPOSE:当前容器对外暴露的端口
WORKDIR:指定在创建容器后,终端默认登陆进来的工作目录,一个落脚点(进入容器之后默认所在的目录位置)
ENTRYPOINT:指定一个容器启动时要运行的命令,与CMD一样。
COPY:类似ADD,拷贝文件 和目录到镜像中。将从构建上下文目录中(源路径)的文件 /目录复制到新的一层的镜像内(目标路径 )位置
FROM mcr.microsoft.com/dotnet/aspnet:6.0 COPY . /unit8 WORKDIR /unit8 EXPOSE 8888 ENTRYPOINT ["dotnet", "Step4.Unit8.dll","--urls","http://0.0.0.0:8888"]
ENV:用来在构建镜像过程中设置环境变量(可理解为事先定义了一个变量,可参考官网的tomcat案例)
ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包(比COPY命令更强大)
VOLUME:容器数据卷,用于数据保存和持久化工作
CMD:指定一个容器启动时要运行的命令,如果有多个CMD命令,则只有最后一个生效。如果指定了 ENTRYPOINT,则CMD表示传参。CMD命令会被docker run 之后的参数替换掉(可以恶意在docker run 后 面加/bin/bash 参数)。
FROM mcr.microsoft.com/dotnet/aspnet:6.0 MAINTAINER 任我行 ENV DOTNET_HOME=/app WORKDIR $DOTNET_HOME ADD ./unit8 $DOTNET_HOME # 相对路径是相对Dockerfile所在目录的路径 EXPOSE 8888 ENTRYPOINT ["dotnet","Step4.Unit8.dll"] CMD ["--urls","http://0.0.0.0:8888"]
ONBUILD:当构建一个被继承的Dockerfile时运行命令,父镜像在被 子继承后父镜像的onbuild被 触发。
我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。
但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。 需要注意的是,如果是再利用B镜像构造新的镜像时,那个ONBUILD指令就无效了,也就是说只能再构建子镜像中执行,对孙子镜像构建无效
4.构建镜像
语法:docker build [-f Dockerfile文件名] -t 新镜像名:[TAG]
-
-t:表示指定镜像名
-
-f 表示指定Dockerfile文件名,若未指定,默认会扫描当前目录下名称为Dockerfile文件
-
注意:最好在你的项目目录中将Dockerfile文件放进来,并在当前目录下执行docker build
例如:
docker build -f ./Dockerfile -t new_redis .
大坑:最后的那个. 千万不要忘记了!!!!
5. 镜像压缩
目的:主要是为了方便镜像的传输
语法:docker save -o 文件名.tar 镜像名:版本号
如:
docker save -o product.tar productservice:1.0
7. 导入为镜像文件
目的:将镜像压缩包解压成镜像文件
语法:docker load --input 文件名.tar
如:
docker load --input productservice.tar
8. 虚悬镜像
虚悬镜像(dangling image) , 那些没有标签的镜像被称为悬虚镜像,在列表中展示为 <none> :
<none> <none> 00285df0df87 5 days ago 342 MB
通常出现这种情况,是因为构建了一个新镜像,然后为该镜像打了一个已经存在的标签。当此情况出现,Docker
会构建新的镜像,然后发现已经有镜像包含相同的标签,接着Docker会移除旧镜像上面的标签,将该标签标在新的镜像之上。例如,首先基于alpine:3.4构建一个新的镜像,并打上dodge:challenger
标签。然后更新Dockerfile
,将alpine:3.4
替换为alpine:3.5
,并且再次执行docker image build
命令。该命令会构建一个新的镜像,并且标签为dodge:challenger
,同时移除了旧镜像上面对应的标签,旧镜像就变成了悬虚镜像
-
查询显示虚悬镜像
docker images -f dangling=true
-
删除虚悬镜像
一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的
docker rmi $(docker images -q -f dangling=true)
或者
docker image prune
配套视频链接:全网首发java/.net双案例Docker精品课程,Docker 进阶教程(双语言双案例助力教学)-已完结_哔哩哔哩_bilibili