Docker学习笔记(三)Dockerfile

一、什么是Dockerfile

        Dockerfile 是一个用于自动化构建 Docker 镜像的文本文件,其中包含了从一个基础镜像开始,到最终形成所需定制镜像的所有指令集。这个文件中的每一条指令都对应着构建镜像过程中的一个步骤或一层,指导 Docker 如何安装软件、设置环境变量、复制文件、开启端口以及配置运行时的各种参数等。说白了就是可以自定义自己的镜像。

二、使用 Dockerfile 定制镜像

        1.下面以定制一个 ubuntu 镜像

        在根目录下新建一个Dockerfile目录(名字随意),切换到该目录然后编辑一个名为Dockerfile(必须是这个名字)的文件,编写如下代码:

FROM ubuntu:latestWORKDIR /appCOPY . /appRUN apt-get update && apt-get install -y python3ENV MY_VAR="value"EXPOSE 8080CMD ["python3", "app.py"]

过程如下:

 2.指令解析

dockerfile指令大全

Dockerfile 指令

说明

FROM

指定基础镜像,用于后续的指令构建。

MAINTAINER

指定Dockerfile的作者/维护者。

LABEL

添加镜像的元数据,使用键值对的形式。

RUN

在构建过程中在镜像中执行命令。

CMD

指定容器创建时的默认命令。(可以被覆盖)

ENTRYPOINT

设置容器创建时的主要命令。(不可被覆盖)

EXPOSE

声明容器运行时监听的特定网络端口。

ENV

在容器内部设置环境变量。

ADD

将文件、目录或远程URL复制到镜像中。

COPY

将文件或目录复制到镜像中。

VOLUME

为容器创建挂载点或声明卷。

WORKDIR

设置后续指令的工作目录。

USER

指定后续指令的用户上下文。

ARG

定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。

ONBUILD

当该镜像被用作另一个构建过程的基础时,添加触发器。

STOPSIGNAL

设置发送给容器以退出的系统调用信号。

HEALTHCHECK

定义周期性检查容器健康状态的命令。

SHELL

覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。

以下是一 

FROM

        FROM是Dockerfile中的第一个指令,也是一个必须的指令。它用于指定构建新镜像时所基于的基础镜像。基础镜像可以是官方的Docker镜像,也可以是其他人或组织发布在Docker Hub或其他容器注册表中的镜像。

格式:FROM <image>FROM <image>:<tag>
示例:FROM nginx:1.25.1-alpine 默认不写使用latest版本的基础镜像

MAINTAINER

                用于指定镜像的维护者信息。它的作用和用法与LABEL指令类似,用于为镜像添加作者、维护者、联系方式等元数据。

格式:MAINTAINER <name>
示例:MAINTAINER PENG MAINTAINER xxx@qq.com

LABEL

        用于向构建的镜像添加元数据(metadata)。这些元数据以键值对的形式存在,可以用来标注关于镜像的各种信息,比如版本号、作者、创建日期、描述等。元数据对于镜像的管理和追踪非常有用,它们可以帮助用户更好地理解和分类不同的镜像。

格式:LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:LABEL version="1.0" \author="John Doe" \description="This image contains a web server with application XYZ" \release-date="2024-05-15"

RUN

        RUN是Dockerfile中的一个重要指令,用于在镜像中执行命令,以便在构建过程中安装软件包、配置环境、生成文件等。RUN指令执行的命令会在新的镜像层中运行,并且在后续构建中,只有在该层之前的内容发生变化时才会重新运行,利用了Docker的缓存机制,提高了构建速度。RUN指令可以接受多种格式的命令执行方式:Shell 格式:默认情况下,RUN指令使用Shell来执行命令。

shell格式:RUN apt-get update && apt-get install -y python3
Exec格式:RUN ["apt-get", "update"]RUN ["apt-get", "install", "-y", "python3"]

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \&& tar -xvf redis.tar.gz

CMD

        CMD是Dockerfile中的一个重要指令,用于定义容器启动时默认要执行的命令。一个Dockerfile中只能包含一个CMD指令,如果有多个,则只有最后一个CMD指令会生效。CMD指令有两种格式:Shell 格式:使用Shell格式时,命令会在Shell中执行。

shell格式:CMD python app.py
Exec格式: 使用数组格式时,命令不会在Shell中执行,而是直接在容器中执行。CMD ["python", "app.py"]

        使用CMD指令可以为镜像定义一个默认的启动命令,当使用docker run命令启动容器时,如果没有指定其他命令,就会执行CMD中定义的命令。这使得在创建容器时无需手动指定要运行的命令,从而使容器的使用更加简便。如果在docker run命令中指定了其他命令,则会覆盖CMD指令中的默认命令。例如,如果在启动容器时执行以下命令,就会覆盖CMD中定义的默认启动命令:

docker run my_image python script.py

在上面的例子中,容器会运行python script.py命令,而不是默认的CMD指令中定义的命令。

ENTRYPOINT

        ENTRYPOINT是Dockerfile中的一个重要指令,用于配置容器启动时的默认执行命令。它类似于CMD指令,但有一些关键的区别。ENTRYPOINT指令的格式与CMD指令类似,可以使用Shell格式或数组格式,但在使用时,需要注意以下几点:

  1. ENTRYPOINT指令的命令会在容器启动时始终执行,无论在docker run命令中是否指定了其他命令。它不会被覆盖,而是作为容器的主要执行命令。
  2. 如果在docker run命令中指定了其他命令,这些命令将作为ENTRYPOINT指令的参数进行传递。也就是说,ENTRYPOINT指令中的命令将成为执行时的前缀。

下面是一个使用ENTRYPOINT指令的简单示例:

FROM ubuntu:latestENTRYPOINT ["echo", "Hello"]

如果我们构建该镜像并运行容器,不提供其他参数,那么容器启动后将输出 "Hello":

$ docker build -t my_image .
$ docker run my_image
Hello

 如果我们在运行容器时提供了其他参数,那么这些参数将作为ENTRYPOINT指令中命令的参数:

$ docker run my_image "World"
Hello World

注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

EXPOSE

       仅仅只是声明端口。

作用:

  • 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
  • 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:EXPOSE <端口1> [<端口2>...]

ENV

        设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

格式:ENV <key> <value>ENV <key1>=<value1> <key2>=<value2>...
示例:FROM ubuntu:latest# 设置环境变量ENV MY_NAME John DoeENV APP_HOME /app# 创建目录并设置工作目录RUN mkdir $APP_HOMEWORKDIR $APP_HOME# 复制应用程序到镜像中COPY . .# 在运行时输出环境变量CMD echo "Hello, $MY_NAME"

        在上面的例子中,我们使用了两个ENV指令来设置两个环境变量:MY_NAME和APP_HOME。在镜像构建过程中,这些环境变量会被设置为指定的值。然后,在容器启动时,CMD指令中的命令将使用$MY_NAME环境变量的值输出问候语。在运行容器时,你可以通过docker run命令的-e选项来覆盖环境变量的值。例如:

$ docker run -e MY_NAME="Alice" my_image

上述命令将覆盖默认的MY_NAME环境变量值,容器将输出 "Hello, Alice"。

ARG

        构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。

构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。

格式:ARG <参数名>[=<默认值>]
示例:FROM ubuntu:latest# 定义构建参数ARG MY_ENV=production# 使用构建参数设置环境变量ENV ENVIRONMENT=$MY_ENV

在上面的例子中,我们通过ARG指令定义了一个名为MY_ENV的构建参数,并设置了其默认值为production。然后,在FROM指令之后,我们使用构建参数设置了一个名为ENVIRONMENT的环境变量。在构建镜像时,可以通过--build-arg选项来指定构建参数的值,例如:

$ docker build --build-arg MY_ENV=development -t my_image .

COPY

        复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

格式:COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
示例:COPY hom* /mydir/

[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。

<目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

ADD

        ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

VOLUME

        VOLUME于声明容器中的挂载点(数据卷)。数据卷是一个特殊的目录,它可以绕过联合文件系统(UnionFS),并在容器间共享数据。VOLUME指令的格式是VOLUME ["/path/to/directory"],其中/path/to/directory是挂载点的路径。可以在一个Dockerfile中使用多个VOLUME指令来声明多个挂载点。

格式:VOLUME ["<路径1>", "<路径2>"...]VOLUME <路径>
示例:FROM ubuntu:latest# 声明两个挂载点VOLUME ["/app/data", "/app/logs"]

在上面的例子中,我们声明了两个挂载点/app/data和/app/logs,这样在运行容器时,可以将这两个挂载点映射到主机的文件系统中,以实现数据持久化和共享。在运行容器时,可以使用-v选项或--mount选项来将主机的目录或数据卷映射到容器的挂载点。例如:

$ docker run -v /host/data:/app/data -v /host/logs:/app/logs my_image

上述命令将主机的/host/data和/host/logs目录分别映射到容器中的/app/data和/app/logs挂载点,实现了主机和容器之间的数据共享。

WORKDIR

        WORKDIR用于设置工作目录,也称为当前工作目录。在容器启动时,进程的当前工作目录将被设置为WORKDIR指令所指定的目录。我们使用WORKDIR指令将工作目录设置为/app,

FROM ubuntu:latest# 设置工作目录
WORKDIR /app# 容器启动时运行的命令
CMD ["python", "app.py"]

         当容器启动时,进程的当前工作目录将自动设置为/app,这样在执行CMD指令时,不需要使用绝对路径来运行python app.py。

USER

        USER用于指定在容器中运行镜像时要使用的非特权用户。默认情况下,Docker容器在启动时以root用户身份运行,这意味着容器内的进程具有最高权限。然而,为了加强安全性,避免潜在的安全风险,最好以非特权用户的身份运行容器中的应用程序。以下是一个简单的示例:

FROM ubuntu:latest# 创建一个新用户并切换到该用户
RUN useradd -ms /bin/bash myuser
USER myuser# 设置工作目录
WORKDIR /app# 复制应用程序到工作目录
COPY . .# 设置环境变量
ENV APP_ENV production# 容器启动时运行的命令
CMD ["python", "app.py"]

        在上面的例子中,我们使用useradd命令创建了一个名为myuser的新用户,并使用-ms /bin/bash选项指定了创建用户时使用的shell。然后,通过USER指令切换到了myuser用户。这样,在容器运行时,进程将以myuser用户的身份运行,而不是以root用户身份。

三、构建镜像

以下是一个简单的Dockerfile示例:

# 使用官方的Ubuntu 20.04镜像作为基础镜像
FROM ubuntu:20.04# 设置工作目录
WORKDIR /app# 复制应用程序到镜像中
COPY . .# 安装应用程序所需的依赖
RUN apt-get update && apt-get install -y python3# 设置环境变量
ENV APP_ENV production# 容器启动时运行的命令
CMD ["python3", "app.py"]

构建镜像:docker build命令:

docker build -t my_image .

-t: 是指定镜像名

        docker build命令会根据Dockerfile的内容,逐条执行其中的指令,并创建一个新的镜像。构建过程会根据每条指令的内容,生成新的镜像层。每条指令都会在上一层的基础上进行修改,最终构建出一个完整的镜像。基于参数构建镜像。

构建完后用命令docker images查看刚刚构建的镜像:

参考文章: 万字长文带你看全网最详细Dockerfile教程-腾讯云开发者社区-腾讯云 (tencent.com) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PHP智慧门店微信小程序系统源码

&#x1f50d;【引领未来零售新风尚】&#x1f50d; &#x1f680;升级启航&#xff0c;智慧零售新篇章&#x1f680; 告别传统门店的束缚&#xff0c;智慧门店v3微信小程序携带着前沿科技与人性化设计&#xff0c;正式启航&#xff01;这个版本不仅是对过往功能的全面优化&a…

从GREE格力看如何起全球商标名称!

有些主体需要走出去出口到国外&#xff0c;普推商标知产老杨看到在一些海外电商平台的出售产品&#xff0c;也会需要英文商标&#xff0c;有的会申请申请注册中英结合商标&#xff0c;在国外申请注册也是比较方便。 格力开始想用“GLEE”(快乐)这个词作为商标名称&#xff0c;但…

【JavaWeb程序设计】JSP编程II

目录 一、输入并运行下面的import_test.jsp页面 1.1 代码运行结果 1.2 修改编码之后的运行结果 二、errorPage属性和isErrorPage属性的使用 2.1 下面的hello.jsp页面执行时将抛出一个异常&#xff0c;它指定了错误处理页面为errorHandler.jsp。 2.1.2 运行截图 2.2 下面…

医疗器械FDA | FDA如何对医疗器械网络安全认证进行审查?

FDA医械网络安全文件出具​https://link.zhihu.com/?targethttps%3A//www.wanyun.cn/Support%3Fshare%3D24315_ea8a0e47-b38d-4cd6-8ed1-9e7711a8ad5e FDA对医疗器械的网络安全认证进行审查时&#xff0c;主要关注以下几个方面&#xff0c;以确保医疗器械在网络环境中的安全性…

2 极/2 零 (2P2Z) 补偿器

极/2 零 &#xff08;2P2Z&#xff09; 补偿器是模拟 II 型控制器的数字实现。它是一种滤波器&#xff0c;通过考虑两个极点和一个零点&#xff0c;将特定的增益和相位升压引入系统。您必须战略性地选择每个极点和零点的频率位置&#xff0c;这将有助于实现所需的系统性能。在该…

团队编程:提升代码质量与知识共享的利器

目录 前言1. 什么是团队编程&#xff1f;1.1 团队编程的起源1.2 团队编程的工作流程 2. 团队编程的优势2.1 提高代码质量2.2 促进知识共享2.3 增强团队协作2.4 提高开发效率 3. 团队编程的挑战3.1 开发成本较高3.2 需要良好的团队协作3.3 个人风格和习惯的差异3.4 长时间的集中…

大数据期末复习——hadoop、hive等基础知识

一、题型分析 1、Hadoop环境搭建 2、hadoop的三大组件 HDFS&#xff1a;NameNode&#xff0c;DataNode&#xff0c;SecondaryNameNode YARN&#xff1a;ResourceManager&#xff0c;NodeManager &#xff08;Yarn的工作原理&#xff09; MapReduce&#xff1a;Map&#xff0…

七人互助拼团模式:共创共赢的电商新篇章

在当今电商行业的繁荣浪潮中&#xff0c;七人互助拼团模式犹如一股清流&#xff0c;凭借其独特的激励机制与深厚的互助合作文化&#xff0c;赢得了消费者与商家的广泛赞誉。这一模式不仅重新定义了团购体验&#xff0c;更在无形中强化了社群间的联系与协作&#xff0c;共同绘制…

中英双语介绍日本东京(Tokyo)

中文版 东京介绍 东京是日本的首都&#xff0c;也是日本的政治、经济、文化和国际交流中心。以下是对东京的详细介绍&#xff0c;包括其地理位置、人口、经济、教育、文化和主要景点。 地理位置 东京位于日本关东地区的南部&#xff0c;地理坐标大致为北纬35度41分&#xf…

C语言_练习题

求最小公倍数 思路&#xff1a;假设两个数&#xff0c;5和7&#xff0c;那么最小至少也要7吧&#xff0c;所以先假定最小公倍数是两个数之间较大的&#xff0c;然后看7能不能同时整除5和7&#xff0c;不能就加1继续除 int GetLCM(int _num1, int _num2) {int max _num1>_n…

C++11中新特性介绍-之(二)

11.自动类型推导 (1) auto类型自动推导 auto自动推导变量的类型 auto并不代表某个实际的类型&#xff0c;只是一个类型声明的占位符 auto并不是万能的在任意场景下都能推导&#xff0c;使用auto声明的变量必须进行初始化&#xff0c;以让编译器推导出它的实际类型&#xff0c;…

Python入门 2024/7/6

目录 数据容器入门 列表的定义语法 基本语法 嵌套列表 ​编辑 列表的下表索引 ​编辑 列表的常用操作 列表的常见方法 查找元素的下标 修改下标索引的值 插入元素 追加元素 追加一批元素 删除元素 删除某元素在列表中的第一个匹配项 清空列表内容 统计元素在…

2024亚太杯中文赛数学建模B题完整论文讲解(含每一问python代码+结果+可视化图)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛B题洪水灾害的数据分析与预测完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人…

web服务之Nginx

web服务之Nginx &#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Li…

将IConfiguration对象转换成一个具体的对象,以面向对象的方式来使用配置

我们倾向于将IConfiguration对象转换成一个具体的对象&#xff0c;以面向对象的方式来使用配置&#xff0c;我们将这个转换过程称为配置绑定。除了将配置树叶子节点配置节的绑定为某种标量对象外&#xff0c;我们还可以直接将一个配置节绑定为一个具有对应结构的符合对象。除此…

【音视频 | RTSP】RTSP协议详解 及 抓包例子解析(详细而不赘述)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

华为开发者大会2024纪要:鸿蒙OS的全新篇章与AI大模型的革命

华为开发者大会2024纪要:鸿蒙OS的全新篇章与AI大模型的革命 在科技的浪潮中,华为再次引领潮流,2024年的开发者大会带来了一系列令人瞩目的创新成果。从鸿蒙操作系统的全新Beta版到盘古大模型的震撼发布,华为正以前所未有的速度重塑智能生态。以下是本次大会的亮点,让我们…

MUNIK解读ISO26262--系统架构

功能安全之系统阶段-系统架构 我们来浅析下功能安全系统阶段重要话题——“系统架构” 目录概览&#xff1a; 系统架构的作用系统架构类型系统架构层级的相关安全机制梳理 1.系统架构的作用 架构的思维包括抽象思维、分层思维、结构化思维和演化思维。通过将复杂系统分解…

哨兵1SAR空间数据包协议数据单元文档(七)

《哨兵1SAR空间数据包协议数据单元》文档对数据包的结构进行了详细描述&#xff0c;并提供了用户数据的格式和解码算法。 原文链接: 哨兵1SAR空间数据包协议数据单元文档英文版 同系列中的其他文章篇链接: 哨兵1SAR空间数据包协议数据单元文档&#xff08;一&#xff09; 哨兵…

lodash-es 基本使用

中文文档&#xff1a;https://www.lodashjs.com/ cloneDeep方法文档&#xff1a;https://www.lodashjs.com/docs/lodash.cloneDeep#_clonedeepvalue 参考掘金文章&#xff1a;https://juejin.cn/post/7354940462061715497 安装&#xff1a; pnpm install lodash-esnpm地址&a…