六、Dockerfile解析

发布时间 2023-11-29 13:58:23作者: 誉尚学教育

课前思考:

分别准备好两个已经写好的.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