涨薪技术|使用Dockerfile创建镜像
上次的推文内容中介绍了如何使用docker commit的方法来构建镜像相反推荐使用被称为Dockerfile的定义文件和docker build命令来构建镜像。Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像之后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像。一、第一个Dockerfile现在来创建一个最简单的Dockerfile文件样例先创建一个空的Dockerfile文件在任意目录下都行在Dockerfile文件中填入以下内容:FROM alpine:3.14 //设置容器内的数据卷 VOLUME [/var/html] EXPOSE 80该Dockerfile由一系列指令和参数组成每条指令如FROM都必须为大写字母且后面跟随一个参数FROM alpine:3.14Dockerfile中的指令会按顺序从上到下执行所以应该根据需要合理安排指令的顺序。使用build命令构建镜像的步骤如下 rootubuntu:/home/test# docker build -t nginx:v1.0 . Sending build context to Docker daemon 8.65MB Step 1/3 : FROM alpine:3.14 3.14: Pulling from library/alpine a0d0a0d46f8b: Pull complete Digest: sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a Status: Downloaded newer image for alpine:3.14 --- 14119a10abf4 Step 2/3 : VOLUME [/var/html] --- Running in baa52a8c37bd Removing intermediate container baa52a8c37bd --- 83ba81539ce7 Step 3/3 : EXPOSE 80 --- Running in b0b0efd15aa3 Removing intermediate container b0b0efd15aa3 --- d10277ba6308 Successfully built d10277ba6308 Successfully tagged nginx:v1.0第一步Docker从基础镜像运行一个容器。第二步执行数据卷指令来创建一个数据卷。第三步设置访问端口最后所有指令执行完毕。每个Dockerfile的第一条指令都应该是FROMFROM指令指定一个已经存在的镜像后续指令都将基于该镜像进行这个镜像被称为基础镜像base iamge。在上面的Dockerfile示例中我们指定了alpine:3.14作为镜像的基础镜像基于这个Dockerfile构建的新镜像将以alpine:3.14操作系统为基础在运行一个容器时必须要指明是基于哪个基础镜像在进行构建。接着是VOLUME指令用于指定数据卷的设置。最后设置EXPOSE指令这条指令告诉Docker该容器内的应用程序将会使用容器的指定端口这并不意味着可以自动访问任意容器运行中服务的端口这里指定的是80端口。二、Dockerfile指令这里主要针对Dockerfile文件中使用到的指令进行介绍介绍Dockerfiler文件中常用的指令在Dockerfile文件中所有的指令都必须使用大写。1)FROMFROM指令的格式如下​​​​​​​FROM [--platformplatform] image [AS name] OR FROM [--platformplatform] image[:tag] [AS name] OR FROM [--platformplatform] image[digest] [AS name]FROM指令表示初始化一个新构建并作为后续指令的基本映像所以一个有效的Dockerfile文件必须以FROM指令开始为个镜像也必须是一个有效镜像可以从一些公用库中来获取相应的镜像。但ARG可以放在FROM指令前面关于ARG和FROM如何交互将会在后面介绍。FROM可以在单个Dockerfile中多出现这样可以创建多个映像或将一个构建阶段用作另一个构建阶段的依赖库。FROM指令可以支持由其上一个指令ARG指令声明的变量并传递给FROM指令使用。​​​​​​​ARG CODE_VERSIONlatest FROM base:${CODE_VERSION} CMD /code/run-app FROM extras:${CODE_VERSION} CMD /code/run-extras2.RUNRUN指令有两种运行方式​​​​​​​#shell格式 RUN command #exec格式 RUN [executable, param1, param2] # 例如 # RUN [./test.php, dev, offline] 等价于 RUN ./test.php dev offline注意Dockerfile的指令每执行一次都会在docker上新建一层所以过多无意义的层会造成镜像膨胀过大。​​​​​​​FROM centos RUN yum 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 install wget \ wget -O redis.tar.gz http://download.redis.io/releases/redis- 5.0.3.tar.gz \ tar -xvf redis.tar.gz如上以 符号连接命令这样执行后只会创建 1 层镜像。3.CMDCMD指令用于指定一个容器启动时所运行的命令这有点类似于RUN指令但RUN指令是指定镜像被构建时要运行的命令而CMD是指容器启动时所要运行的命令CMD指令有三种形式。​​​​​​​#exec格式 CMD [executable,param1,param2] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数 CMD [param1,param2] #shell格式 CMD command param1 param2一般推荐使用第一种格式执行过程清晰明确。第三种格式其实在运行过程中也会转换成第一种格式运行并且默认可执行文件是sh。CMD和使用docker run命令启动容器时指定运行命令几乎一致。​​​​​​​#如在Dockerfile文件中写以下指令 CMD [/bin/true] #上面这个CMD等同以下面的run指令 rootubunhomhome/test# docker run -it nginx /bin/true在Dockerfile中只能有一个CMD指令即使如果有多个CMD指令也只有最后一个CMD才会生效。CMD指令主要是为执行中的容器提供默认值这些默认值可以包含可执行文件也可以省略可执行文件在这种情况下就必须指定一条ENTRYPOINT指令。如果用户在使用docker run指定参数时则它们将会覆盖Dockerfile文件中的CMD参数默认值。4.LABELLABEL指令用来给镜像添加一些元数据metadata以键值对的形式语法格式如下LABEL keyvalue keyvalue keyvalue ...如果LABEL值中需要跨多行则需要加入反斜杠和引号。​​​​​​​LABEL com.example.vendorchuanshi LABEL com.example.label-with-valuetest LABEL version3.0 LABEL descriptionThis text illustrates \ that label-values can span multiple lines.一个镜像可以有多个标签可以在一行上指定多个标签有以下两种方式可以实现。​​​​​​​LABEL Learn more about the LABEL Dockerfile command. multi.label1value1 multi.label2value2 othervalue3 LABEL multi.label1value1 \ multi.label2value2 \ othervalue35.EXPOSE该指令用于声明监听的端口号在监听是可以指定是TCP还是UDP协议默认值为TCP其主要有以下作用帮助镜像使用理解这个镜像服务的守护端口以方便配置映射。在运行时使用随时端口映射也就是docker run -P时会自动随机映射EXPOSE的端口。EXPOSE指令实际上并未发布指定端口它是将我们访问时输入的端口和运行容器之间做一种关联或通信具体发布哪些端口要在运行容器时发布实际端口可以使用docker run中-p或-P来设置映射的端口号。默认情况下一般如果我们未指定协议的话那么都是使用TCP协议当然也可以指定具体的协议也可以同时指定TCP和UDP协议。​​​​​​​EXPOSE 80/tcp EXPOSE 80/udp6.ENV设置环境变量定义了环境变量这样在后续的指令中就可以使用这个环境变量。如果在环境变量引用过程中包含空格那么需要使用到反斜杠。其语法格式如下​​​​​​​ENV key value ENV key1value1 key2value2... ENV MY_NAMEJohn Doe ENV MY_DOGRex\ The\ Dog ENV MY_CATfluffy使用ENV设置的环境变量会保留下来当容器运行时可以使用docker inspect查看值并且可以使用docker run --env 更改环境变量的值。如果仅仅是在构建过程中需要环境变量而在最终映像中不需要可以考虑为单个命令设置一个值或使用ARGARG指令不会人保留在最终镜像中。​​​​​​​ARG DEBIAN_FRONTENDnoninteractive RUN apt-get update apt-get install -y ...7.ARGARG构建参数与ENV作用一致不过作用域不一样ARG设置的环境变量仅对Dockerfile内有效也就是说只有docker build的过程中有效构建好的镜像内不存在此环境变量。构建命令docker build中可以用--build-arg 参数名值来覆盖ARG指令格式如下ARG 参数名[默认值]如果ARG指令具有默认值并且在构建时未传递任何值则构建时会使用默认值相反如果未设置默认值并且在构建中未传递任何值那么构建时会输出警告信息。8.ADDADD指令是指将宿主机的文件或目录复制到镜像文件系统中指定的路径其语法格式有两种​​​​​​​ADD [--chownuser:group] src... dest ADD [--chownuser:group] [src,... dest]每个可以使用通配符并且匹配将使用Go的filepath.Match规则进行例如要添加所有以“hom”开头的文件ADD hom* /mydir/“”可以替换任意一个字符例如ADD hom?.txt /mydir/是指构建容器的路径可以是绝对路径也可以是相对路径但这个相对路径是相对于WORKDIR的路径。如以下示例是将“test.txt”文件添加到/relativeDir/。ADD test.txt relativeDir/下面的示例则是将“test.txt”添加到相对路径/absoluteDie/中。ADD test.txt /absoluteDir/如果路径中包含一些特字符那么需要按照Golang规则转义那些路径以防止在解析过程中将它们视为匹配的模式如要添加名为sarr[1].txt的文件。ADD sarr[[]1].txt /mydir/路径必须是构建内容的一个内部路径不能添加类似于ADD ../path /path因为docker build的第一步是将上下文目录和子目录发送到docker守护进程。如果是URL而不以斜杠结尾则从URL下载文件并将其复制到。如果是URL而以斜杠结尾则从URL推断文件名并将文件下载到/例如ADD http://chuanshi.com/foobar /将创建文件/foobar该URL必须具有正确的路径以便在这种情况下可以找到适当的文件名。如果是目录则复制目录的整个内容包括文件系统元数据。如果是任何其他类型的文件则会将其及其元数据一起单独复制在这种情况下如果以斜杠结尾则它将被视为目录并且的内容将被写在/base()中。如果直接或由于使用通配符而指定多个资源则必须是目录并且必须以斜杠结尾。如果不以斜杠结尾则将其视为常规文件并且的内容将被写入。如果不存在则会与路径中所有缺少的目录一起创建它。9.COPY复制指令从上下文目录中复制文件或者目录到容器里指定路径通常有以下两种格式​​​​​​​COPY [--chownuser:group] src... dest COPY [--chownuser:group] [src,... dest]COPY指令表示从复制新文件或目录并将它们添加到容器的文件系统中路径为。可以指定多个资源但是文件和目录的路径将被解释为相对于构建上下文。每个可能包含通配 符并且匹配将合作Go人filepath.Match规则进行。例如要添加所有hom开头的文件COPY home* /mydir/?表示可以匹配任意一个字符COPY hom?.txt /mydir/是指构建容器的路径可以是绝对路径也可以是相对路径但这个相对路径是相对于WORKDIR的路径。如以下示例是将“test.txt”文件添加到/relativeDir/。COPY test.txt relativeDir/下面的示例则是将“test.txt”添加到相对路径/absoluteDie/中COPY test.txt /absoluteDir/如果路径中包含一些特字符那么需要按照Golang规则转义那些路径以防止在解析过程中将它们视为匹配的模式如要添加名为sarr[1].txt的文件。COPY sarr[[]1].txt /mydir/路径必须是构建内容的一个内部路径不能添加类似于COPY ../path /path因为docker build的第一步是将上下文目录和子目录发送到docker守护进程。如果是目录则复制目录的整个内容包括文件系统无数据目录本身不会被复制只是其内容被复制。如果是任何其他类型的文件则会将其及其元数据一起单独复制在这种情况下如果以斜杠结尾则它将被视为目录并且的内容将被写在/base()中。如果直接或由于使用通配符而指定多个资源则必须是目录并且必须以斜杠结尾。如果不以斜杠结尾则将其视为常规文件并且的内容将被写入。如果不存在则会与路径中所有缺少的目录一起创建它。10.ENTRYPOINT类似于CMD指令但其不会被docker run指令运行参数所覆盖并且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序。但是如果运行docker run时使用了--entrypoint选项将覆盖CMD指令指定的程序。其语法格式有以下两种​​​​​​​#exec格式 ENTRYPOINT [executable, param1, param2] #shell格式 ENTRYPOINT command param1 param2ENTRYPOINT的优点在执行docker run的时候可以指定ENTRYPOINT运行所需要的参数。但如果Dockerfile中如果存在多个ENTRYPOINT指令时只有最后一个会生效。可以将ENTRYPOINT与CMD命令搭配使用一般是变参才会使用CMD这里的CMD等于是在给ENTRYPOINT传参。例如通过Dockerfile构建了一个nginx:V1.0的镜像。​​​​​​​FROM nginx ENTRYPOINT [nginx, -c] # 定参 CMD [/etc/nginx/nginx.conf] # 变参如果在运行容器时不传参运行rootubunhomhome/test# docker run -it nginx:v1.0容器内则会默认运行以下命令启动主进程nginx -c /etc/nginx/nginx.conf如果在运行容器时传参运行rootubunhomhome/test# docker run -it nginx:v1.0 -c /etc/nginx/new_nginx.conf容器内会默认运行以下命令启动主进程nginx -c /etc/nginxnew_nginx.conf11.VOLUMEVOLUME指令在16.7小节会进行详细的介绍在本小节中不做介绍;12.USERUSER指令用于指定执行后续命令的用户和用户组这边只是切换后续指令执行的用户用户和用户组必须提前已经存在。其语法格式如下​​​​​​​USER user[:group] #or USER UID[:GID]13.WORKDIRWORKDIR指令表示指定工作目录该指定的目录必须提前创建好docker build构建镜像过程中的每个RUN命令都是新建的一层只有通过WORKDIR创建才会一直存在。其语法格式如下WORKDIR /path/to/workdirWORKDIR指令可在Dockerfile中多次使用如果提供了相对路径则它将相对于上一个WORKDIR指令的路径来创建目录如​​​​​​​WORKDIR /a WORKDIR b WORKDIR c RUN pwd该Dockerfile中最后一个pwd命令的输出为/a/b/c。WORKDIR指令也可以解析ENV设置的环境变量如​​​​​​​ENV DIRPATH/path WORKDIR $DIRPATH/$DIRNAME RUN pwd该Dockerfile中最后一个pwd命令的输出为/path/$DIRNAME。下期分享Docker数据卷的知识敬请关注

相关新闻

关于ArrayList  LinkedList remove()方法的一点思考,更改或删除抽象数据类型的值

关于ArrayList LinkedList remove()方法的一点思考,更改或删除抽象数据类型的值

对于基本数据类型和常见的抽象数据类型不做考虑 针对的是由程序编写者创建的抽象数据类型 通过查看API文档,提供了一个remove(Object O)方法** 一. 首先想到的是逐个比较不同节点里的数据,list.remove(index i); ** import java.util.*;/****…

2026/7/28 14:38:17 阅读更多 →
JAVA毕设选题推荐:基于SpringBoot 架构下智能教学辅助咨询系统 人机交互式课程答疑与学习辅助系统【附源码、mysql、文档、调试+代码讲解+全bao等】

JAVA毕设选题推荐:基于SpringBoot 架构下智能教学辅助咨询系统 人机交互式课程答疑与学习辅助系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/28 14:37:17 阅读更多 →
JAVA新手入门知识

JAVA新手入门知识

Java的创始人:James Gosling 1996年发行JDK(Java Development Kit)1.0 JDK(Java Development Kit)是Java语言的软件开发工具包(SDK) JDK分为三个版本: JavaSE Standard Edition 标准版 JavaME Micro Edition 微型版 JavaEE Enterpise Edition 企业版 J…

2026/7/28 14:37:17 阅读更多 →

最新新闻

Java 8 Stream

Java 8 Stream

前言 Stream是Java8的另一大亮点,是对容器对象功能的增强,它专注于对容器对象进行各种非常便利、高效的 聚合操作(aggregate operation)或者大批量数据操作; 准备 流和管道的概念: Stream 以一种流式风格来…

2026/7/28 14:50:21 阅读更多 →
物联网硬件安全:SE050与TM4C129ENCZAD的协同设计

物联网硬件安全:SE050与TM4C129ENCZAD的协同设计

1. 物联网安全现状与硬件级解决方案的必要性在2023年全球物联网连接数突破160亿的背景下,安全事件同比增长了47%。我曾参与过一个智能水表项目,攻击者仅用廉价的SDR设备就成功截获了未加密的计量数据。这种案例揭示了传统MCU在安全防护上的先天不足——缺…

2026/7/28 14:50:21 阅读更多 →
6大主流网盘极速下载终极解决方案:免费开源助手完整指南

6大主流网盘极速下载终极解决方案:免费开源助手完整指南

6大主流网盘极速下载终极解决方案:免费开源助手完整指南 【免费下载链接】baiduyun 油猴脚本 - 一个免费开源的网盘下载助手 项目地址: https://gitcode.com/gh_mirrors/ba/baiduyun 还在为网盘下载速度慢而烦恼吗?这款免费开源的网盘直链下载助手…

2026/7/28 14:50:21 阅读更多 →
物联网设备低功耗设计:NBM7100A与STM32L152RE优化方案

物联网设备低功耗设计:NBM7100A与STM32L152RE优化方案

1. 项目背景与核心挑战在物联网设备和便携式电子产品的设计中,初级电池(不可充电电池)的寿命优化一直是个棘手问题。我曾参与过一个环境监测项目,设备部署在偏远地区,每隔15分钟采集一次温湿度数据并通过LoRa传输。最初…

2026/7/28 14:50:21 阅读更多 →
物联网安全:SE050与PIC18F46K40硬件加密方案详解

物联网安全:SE050与PIC18F46K40硬件加密方案详解

1. 物联网安全现状与SE050的定位在2023年全球物联网设备数量突破430亿台的背景下,安全事件同比增长了67%。我曾参与过多个工业物联网项目,亲眼见证过因密钥硬编码导致的生产线被勒索软件加密的案例。恩智浦的EdgeLock SE050系列安全元件正是为解决这类问…

2026/7/28 14:50:20 阅读更多 →
果树在西北App隐私政策

果树在西北App隐私政策

果树在西北隐私政策尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,果树在西北隐私政策会按照本隐私权政策的规定使用和披露您的个人信息。但果树在西北隐私政策将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外&a…

2026/7/28 14:49:20 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻