Docker:镜像构建 DockerFile

news2024/11/23 15:21:21

Docker:镜像构建 DockerFile

    • 镜像构建
      • docker build
    • Dockerfile
      • FROM
      • COPY
      • ENV
      • WORKDIR
      • ADD
      • RUN
      • CMD
      • ENTRYPOINT
      • USER
      • ARG
      • VOLUME


镜像构建

Docker官方提供的镜像中,大部分都是基础镜像,他们只提供某个简单的功能,如果想要一个功能更加丰富的镜像,就需要自己制作。

比如说一个容器配置完毕后,想要让容器便于传输,就可以封装为一个镜像。或者说希望让自己的容器可以被别人看到,提交到仓库上去,也要先变为镜像。

Docker指令中,docker commit可以使用快照的形式快速制作一个镜像,它直接将一个容器导出为镜像。除此之外,Docker还提供了另一种方式构建镜像:编写Dockerfile

Dockerfile是一个文件,首字母大小写任意,依据这个文件,就可以构建出一个镜像。在联网的状态下,只要有这个文件,就可以构建出任意的镜像。


docker build

docker bild命令可以读取Dockerfile文件,并依据文件构建镜像。

语法:

docker build [option] path

参数:

  • -f:指定要使用的Dockerfile路径,默认为当前目录下的Dockerfile文件
  • -t:指定镜像的名称与标签

具体使用,在稍后Dockerfile编写时一起讲解。


Dockerfile

Dockerfile是一个文本文件,内部包含多条指令,这些指令描述了如何构建一个镜像,如果构建的镜像不符合要求,还可以修改Dockerfile反复制作镜像。

Dockerfile的不区分大小写,后续的指令都以大写形式。

Dockerfile使用#进行注释:

# 这是一行注释

FROM

  • 功能:指定一个基础镜像

语法:

FROM image[:tag] [AS name]

指定镜像时,可以使用as对这个镜像重命名,这样可以在一个DockerFile中进行多级构建,这个稍后会讲解。

示例:

FROM ubuntu:22.04 AS ubt1
FROM ubuntu:22.04 AS ubt2

使用FROM指定基础镜像时,如果基础镜像不存在,那么会自动拉取。


COPY

  • 功能:从宿主机或者其它镜像中拷贝文件

语法:

COPY [option] src[,src] dst
COPY [option] "src"[,"src"] "dst"

将文件从src拷贝到dst,如果有多个文件,使用逗号分隔。如果在文件名中没有出现空格,可以不用双引号,如果文件名内有空格,就需要使用"src""dst"

选项:

  • --chown:修改用户和组
  • --from:可以从之前的镜像中拷贝文件

拷贝宿主机文件:

FROM ubuntu:22.04
COPY ./test.txt /

以上代码指定了一个ubuntu的基础镜像,并拷贝一个宿主机文件test.txt到根目录下。

通过docker build构建镜像:

在这里插入图片描述

选项-t指定镜像名为my-ubuntu:v1,随后开始执行Dockerfile内部的指令,可以看到[2/2]COPY ./test.txt /,这就是之前写的COPY指令。

实例化一个容器:

在这里插入图片描述

进入容器后,根目录就多出了test.txt文件,这是构建镜像时拷贝进去的。

除此之外,还可以进行多级构建,所谓的多级构建,就是可能最终镜像内部的文件来自不同环境。那么先在某些镜像环境内部生成所需的文件,再把文件拷贝到最终的镜像内。

示例:

FROM nginx AS build-stage

FROM ubuntu
COPY --from=build-stage /usr/share/nginx/html /

以上代码,先创建了一个nginx镜像,重命名为build-stage,随后创建一个ubuntu镜像,在ubuntu镜像中,拷贝来自build-stage的内容,把目录/usr/share/nginx/html下的文件拷贝到自己的根目录。

多级构建时,最终的镜像是最后一个FROM指定的镜像,前面指定的镜像都是为了生成某些文件。

构建镜像:

在这里插入图片描述

最终生成一个my-ubuntu:v2镜像。

进入镜像:

在这里插入图片描述

进入后,根目录多出了index.html,输出后得到一个Welcome to nginx!的网页文件,这个文件就是在nginx镜像生成的,最后拷贝到了ubuntu中。


ENV

  • 功能:设置环境变量

语法:

ENV name=value 

环境变量不仅可以在容器内部使用,还可以在后文通过${}引用。

示例:

FROM nginx AS build-stage

FROM ubuntu
ENV ngx_path=/usr/share/nginx/html
COPY --from=build-stage ${ngx_path} /

定义了一个环境变量ngx_path,后续可以直接通过${ngx_path}取出变量值。


WORKDIR

  • 功能:修改工作目录

语法:

WORKDIR path

在构建镜像时,默认的工作目录都是/根目录,如果想要切换目录,可以使用WORKDIR

示例:

FROM nginx
WORKDIR /usr/share/nginx/html
COPY ./test.txt ./

以上代码,把宿主机的./test.txt文件拷贝到容器的/usr/share/nginx/html目录下。

因为修改了WORKDIR,所以./就是/usr/share/nginx/html


ADD

  • 功能:将文件添加到镜像中,可以解压缩tar压缩文件

语法:

ADD src dst

选项:

  • --chown:修改文件所有者和组

此处的COPY非常类似COPY,用法也是一致的,功能都是拷贝文件。

但是ADDCOPY更强大,如果src是压缩包,那么会自动完成解压缩。如果src是一个url,还会完成自动下载

示例:

FROM ubuntu:22.04
ADD ./test.tar /

test.tar文件,通过ADD命令,添加到镜像的根目录中。

输出结果:

在这里插入图片描述

创建完镜像再启动后,根目录下的内容不是test.tar而是test.txt,说明文件被自动解压了。


RUN

  • 功能:在构建镜像的过程中执行命令

语法:

RUN command
RUN ["command", "arg1", "arg2",...]

在构建镜像的过程中,可以通过RUN执行指定命令,两种语法中,他们的效果其实是不一样的。

直接RUN command,会以/bin/sh -c来执行指令,这可以提供一些bash的特性,比如可以使用通配符? *等进行替换,以及运行.sh程序等。

但是使用[]的形式执行命令,不会具有bash特性。

示例:

FROM ubuntu:22.04
COPY ./test* /
RUN mkdir dir1
RUN mkdir dir2
RUN cp ./test* dir1
RUN ["cp", "./test*", "dir2"]

以上代码,把宿主机的./test*拷贝到镜像的根目录,这是一个通配符,可以拷贝多个文件。

随后通过RUN执行mkdir命令,创建了两个目录。最后把从宿主机拷贝来的文件再拷贝到目录里面,分别使用RUN commandRUN []两种语法。

输出结果:

在这里插入图片描述

在当前目录下,有testtest.cpptest.javatest.txt四个文件,构建镜像时,可以看到RUN cp ./test* dir1执行成功了,但是RUN ["cp", "./test*", "dir2"]失败了。

因为RUN []不支持bash特性,导致无法匹配./test*通配符,最后显示找不到./test*这个文件。


CMD

  • 功能:指定容器启动时执行的命令

语法:

CMD ["command","arg1","arg2",...]
CMD command arg1 arg2 ...

其中CMD commandCMD []的两种形式,和之前的RUN一样,重点在于是否具有shell
特性。

示例:

FROM ubuntu:22.04
CMD ["echo", "hello world"]

这个镜像,在启动时会执行CMD内的命令,输出hello world字符串。

在这里插入图片描述

原先ubuntuCMDbash,也就是进入命令行,由于输出字符串的命令将其覆盖了,所以无法直接进入命令行。

除此之外,CMD的命令还会进行覆盖,比如Dockerfile内部的多个CMD,后面的会覆盖前面的:

FROM ubuntu:22.04
CMD ["echo", "hello world"]
CMD ["echo", "hello C++"]
CMD ["echo", "hello Docker"]

最后该镜像的命令是echo “hello Docker”,前两个被覆盖了。

除此之外,在启动容器时用户也可以指定命令,这个命令也可以覆盖CMD

在这里插入图片描述


ENTRYPOINT

  • 功能:指定容器启动时执行的命令

语法:

ENTRYPOINT ["command", "arg1", "arg2",...]
ENTRYPOINT command arg1 arg2 ...

ENTRYPOINTCMD的功能是一样的,但是语法特性略有差别。

CMD中,后面的CMD会覆盖前面的CMD,启动容器时的命令也会覆盖CMD

ENTRYPOINT中,一个Dockerfile只有最后一个ENTRYPOINT生效,但是用户输入命令时,会变成ENTRYPOINT的参数,而不是覆盖。

示例:

FROM ubuntu:22.04
ENTRYPOINT ["echo", "hello world"]

在这里插入图片描述

构建成功后,在启动容器时指定命令echo "hello Docker",输出结果却不是hello Docker,而是:

hello world echo hello Docker

这是因为后面的echo "hello Docker"都变成了ENTRYPOINT内部的指令的参数,最后相当于执行:

echo "hello world" "echo" "hello Docker"

USER

  • 功能:指定运行容器时的用户或用户ID

语法:

USER user[:group]

默认情况下用户为root,可以通过USER命令修改后文执行指令时的用户。

示例:

FROM ubuntu:22.04
RUN useradd new_usr
USER new_usr
WORKDIR /home/new_usr

以上代码,通过RUN创建了一个new_usr用户,并切换用户为new_usr

输出结果:

在这里插入图片描述

创建容器后,默认用户就是new_usr,并且处于该用户的家目录中。


ARG

  • 功能:定义构建时的变量

语法:

ARG name[=value]

这个用于指定一些参数,这个参数可以在Dockerfile中通过${}引用。

示例:

FROM ubuntu:22.04
ARG path=/home/new_usr
RUN useradd new_usr
USER new_usr
WORKDIR ${path}

将刚才的用户家目录定义在参数path中,后续可以直接通过${path}引用。


VOLUME

  • 功能:创建一个匿名卷,并指定挂载点

语法:

VOLUME ["path"]
VOLUME path

由于镜像实例化时,用户所处的路径是不确定的,就算确定了路径,也不保证用户存在这个路径,所以在镜像构建阶段不能创建绑定卷,只能创建匿名卷。

VOLUME的参数中,指定的path就是要进行绑定的匿名卷,可以持久化一些重要数据,就算容器崩溃,用户也有机会找回数据。


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

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

相关文章

《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>

PS:关于接口定义 接口定义,通常由服务器提供方来定义。 1.路径:自己定义 2.参数:根据需求考虑,我们这个接口功能完成需要哪些信息。 3.返回结果:考虑我们能为对方提供什么。站在对方角度考虑。 我们使用到的…

【JavaEE】文件io

目录 文件类型 File概述 属性 构造方法 常用方法 Reader Writer InputStream OutputStream 字节流转字符流 通过Scanner读取InputStream 通过PrintWriter转换outputstream 示例 文件类型 从编程的角度看,文件类型主要就是两大类 文本(文…

D3入门:概念、主要特点、基本功能、常见应用场景

D3.js(Data-Driven Documents)是一个JavaScript库,用于基于数据操作文档。它利用了HTML、SVG和CSS等Web标准技术,使得开发者可以创建丰富的交互式图表和数据可视化。D3.js的强大之处在于其灵活的数据绑定机制和对DOM元素的高效操作…

go函数传值是值传递?还是引用传递?slice案例加图解

先说下结论 Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。 值语义类型:参数传递的时候,就是值拷贝,这样就在函数中就无法修改原内容数据。 基本类型:byte、int、bool…

tensorflow案例5--基于改进VGG16模型的马铃薯识别,准确率提升0.6%,计算量降低78.07%

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 本次采用VGG16模型进行预测,准确率达到了98.875,但是修改VGG16网络结构, 准确率达到了0.9969,并且计算量…

攻防世界38-FlatScience-CTFWeb

攻防世界38-FlatScience-Web 点开这个here看到一堆pdf,感觉没用&#xff0c;扫描一下 试试弱口令先 源码里有&#xff1a; 好吧0.0 试试存不存在sql注入 根本没回显&#xff0c;转战login.php先 输入1’,发现sql注入 看到提示 访问后得源码 <?php ob_start(); ?>…

数据分析-44-时间序列预测之深度学习方法TCN

文章目录 1 TCN简介1.1 网络示意图1.2 TCN优点2 模拟应用2.1 模拟数据2.2 预处理创建滞后特征2.3 划分训练集和测试集2.4 创建TCN模型2.5 模型训练2.6 模型预测3 自定义my_TCN模型3.1 my_TCN()函数3.2 训练模型3.3 模型预测3.4 改进4 参考附录1 TCN简介 时间卷积网络(TCN)是…

C++【STL容器系列(二)】vector的模拟实现

文章目录 1. vector的结构2. vector的默认成员函数2.1构造函数2.1.1 默认构造2.1.2 迭代器构造2.1.3 用n个val初始化构造 2.2 拷贝构造2.3 析构函数2.4 operator 3. vector iterator函数3.1 begin 和 cbegin函数3.2 end() 和 cend()函数 4. vector的小函数4.1 size函数4.2 capa…

【linux】网络基础 ---- 应用层

1. 再谈 "协议" 协议是一种 "约定"&#xff0c;在读写数据时, 都是按 "字符串" 的方式来发送接收的. 但是这里我们会遇到一些问题&#xff1a; 如何确保从网上读取的数据是否是完整的&#xff0c;区分缓冲区中的由不同客户端发来的数据 2. 网…

C语言PythonBash:空白(空格、水平制表符、换行符)与转义字符

C语言 空白 C语言中的空白&#xff08;空格、水平制表符、换行符&#xff09;被用于分隔Token&#xff0c;因此Token间可以有任意多个空白。 // 例1 printf("Hello, World!"); 例1中存在5个Token&#xff0c;分别是&#xff1a; printf("Hello, World! \n&qu…

Linux基础(十四)——BASH

BASH 1.BASH定义2.shell的种类3.bash的功能3.1 命令记录功能3.2 命令补全功能3.3 命令别名设置3.4 工作控制、 前景背景控制3.5 程序化脚本&#xff1a; &#xff08; shell scripts&#xff09;3.6 万用字符 4.bash的内置命令5.shell的变量功能5.1 变量的取用5.2 新建变量5.3 …

【重学 MySQL】八十二、深入探索 CASE 语句的应用

【重学 MySQL】八十二、深入探索 CASE 语句的应用 CASE语句的两种形式CASE语句的应用场景数据分类动态排序条件计算在 SELECT 子句中使用在 WHERE子句中使用在 ORDER BY 子句中使用 注意事项 在MySQL中&#xff0c;CASE 语句提供了一种强大的方式来实现条件分支逻辑&#xff0c…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

7+纯生信,单细胞识别细胞marker+100种机器学习组合建模,机器学习组合建模取代单独lasso回归势在必行!

影响因子&#xff1a;7.3 研究概述&#xff1a; 皮肤黑色素瘤&#xff08;SKCM&#xff09;是所有皮肤恶性肿瘤中最具侵袭性的类型。本研究从GEO数据库下载单细胞RNA测序&#xff08;scRNA-seq&#xff09;数据集&#xff0c;根据原始研究中定义的细胞标记重新注释各种免疫细胞…

uniapp解析蓝牙设备响应数据bug

本文章为了解决《uniapp 与蓝牙设备收发指令详细步骤(完整项目版)》中第十步的Array 解析成 number函数bug 1、原代码说明 function array16_to_number(arrayValue) {const newArray arrayValue.filter(item > String(item) ! 00 || String(item) ! 0)const _number16 ne…

【递归回溯与搜索算法篇】算法的镜花水月:在无尽的自我倒影中,递归步步生花

文章目录 递归回溯搜索专题&#xff08;一&#xff09;&#xff1a;递归前言第一章&#xff1a;递归基础及应用1.1 汉诺塔问题&#xff08;easy&#xff09;解法&#xff08;递归&#xff09;C 代码实现时间复杂度和空间复杂度易错点提示 1.2 合并两个有序链表&#xff08;easy…

大数据开发面试宝典

312个问题&#xff0c;问题涵盖广、从自我介绍到大厂实战、19大主题&#xff0c;一网打尽、真正提高面试成功率 一、Linux 1. 说⼀下linux的常⽤命令&#xff1f; 说一些高级命令即可 systemctl 设置系统参数 如&#xff1a;systemctl stop firewalld关闭防火墙 tail / hea…

链表归并与并集相关算法题|两递增归并为递减到原位|b表归并到a表|两递减归并到新链表(C)

两递增归并为递减到原位 假设有两个按元素递增次序排列的线性表&#xff0c;均以单链表形式存储。将这两个单链表归并为一个按元素递减次序排列的单链表&#xff0c;并要求利用原来两个单链表的节点存放归并后的单链表 算法思想 因为两链表已按元素值递增次序排列&#xff0…

【RabbitMQ】06-消费者的可靠性

1. 消费者确认机制 没有ack&#xff0c;mq就会一直保留消息。 spring:rabbitmq:listener:simple:acknowledge-mode: auto # 自动ack2. 失败重试机制 当消费者出现异常后&#xff0c;消息会不断requeue&#xff08;重入队&#xff09;到队列&#xff0c;再重新发送给消费者。…

【陕西】《陕西省省级政务信息化项目投资编制指南(建设类)(试行)》-省市费用标准解读系列07

《陕西省省级政务信息化项目投资编制指南&#xff08;建设类&#xff09;&#xff08;试行&#xff09;》规定了建设类项目的费用投资测算方法与计价标准&#xff0c;明确指出建设类项目费用包括项目建设费和项目建设其他费&#xff08;了解更多可直接关注咨询我们&#xff09;…