dockerfile介绍与使用

文档:https://docs.docker.com/engine/reference/builder/

dockerfile介绍

dockerfile是什么

Dockerfile是一个创建镜像所有命令的文本文件, 包含了一条条指令和说明, 每条指令构建一层, 通过 docker build命令,根据Dockerfile的内容构建镜像,因此每一条指令的内容, 就是描述该层如何构建.有了 Dockefile, 就可以制定自己的docker镜像规则,只需要在Dockerfile上添加或者修改指令, 就可生成 docker 镜像.

dockerfile解决了什么问题

Dockerfile 包含了镜像制作的完整操作流程,其他开发者可以通过 Dockerfile 了解并复现制作过程 Dockerfile 中的每一条指令都会创建新的镜像层,这些镜像可以被 Docker Daemon 缓存。再次制作镜 像时,Docker 会尽量复用缓存的镜像层(using cache),而不是重新逐层构建,这样可以节省时间和 磁盘空间 Dockerfile 的操作流程可以通过docker image history [镜像名称]查询,方便开发者查看变更记录

docker build 构建流程

docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终 Docker 引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。
第一步,docker build会将 context 中的文件打包传给 Docker daemon。如果 context 中 有.dockerignore文件,则会从上传列表中删除满足.dockerignore规则的文件。注意:如果上下文中有相当多的文件,可以明显感受到整个文件发送过程。
这里有个例外,如果.dockerignore文件中有.dockerignore或者Dockerfile,docker build命令在排除文件时会忽略掉这两个文件。如果指定了镜像的 tag,还会对 repository 和 tag 进行验证。
第二步,docker build命令向 Docker server 发送 HTTP 请求,请求 Docker server 构建镜像,请求中 包含了需要的 context 信息。
第三步,Docker server 接收到构建请求之后,会执行以下流程来构建镜像:
1. 创建一个临时目录,并将 context 中的文件解压到该目录下。
2. 读取并解析 Dockerfile,遍历其中的指令,根据命令类型分发到不同的模块去执行。
3. Docker 构建引擎为每一条指令创建一个临时容器,在临时容器中执行指令,然后 commit 容器, 生成一个新的镜像层。
4. 最后,将所有指令构建出的镜像层合并,形成 build 的最后结果。最后一次 commit 生成的镜像 ID 就是最终的镜像 ID。

为了提高构建效率,docker build默认会缓存已有的镜像层。如果构建镜像时发现某个镜像层已经被缓 存,就会直接使用该缓存镜像,而不用重新构建。如果不希望使用缓存的镜像,可以在执行docker build命令时,指定--no-cache=true参数。

Docker 匹配缓存镜像的规则为:遍历缓存中的基础镜像及其子镜像,检查这些镜像的构建指令是否和当 前指令完全一致,如果不一样,则说明缓存不匹配。对于ADD、COPY指令,还会根据文件的校验和 (checksum)来判断添加到镜像中的文件是否相同,如果不相同,则说明缓存不匹配。 这里要注意,缓存匹配检查不会检查容器中的文件。比如,当使用RUN apt-get -y update命令更新了容 器中的文件时,缓存策略并不会检查这些文件,来判断缓存是否匹配。 最后,可以通过docker history命令来查看镜像的构建历史。

关键字
FROM 设置镜像使用的基础镜像
MAINTAINER 设置镜像的作者
RUN 编译镜像时运行的脚步
CMD 设置容器的启动命令
LABEL 设置镜像标签
EXPOSE 设置镜像暴露的端口
ENV 设置容器的环境变量
ADD 编译镜像时复制上下文中文件到镜像中
COPY 编译镜像时复制上下文中文件到镜像中
ENTRYPOINT 设置容器的入口程序
VOLUME 设置容器的挂载卷
USER 设置运行 RUN CMD ENTRYPOINT的用户名
WORKDIR 设置 RUN CMD ENTRYPOINT COPY ADD 指令的工作目录
ARG 设置编译镜像时加入的参数
ONBUILD 设置镜像的ONBUILD 指令
STOPSIGNAL 设置容器的退出信号量

dockerfile 实践

基本语法实践
mkdir example
cd example

vim Dockerfile

FROM golang
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
# 仅指定镜像元数据内容
LABEL hello 1.0.0
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
docker build -t hello:1.0.0 -f Dockerfile .
docker run -p 80:80 -d --name hello hello:1.0.0

构建成功:​​​​​​​

docker build上下文 

1. 素材准备

# 创建一个目录,案例需要
mkdir example2
cd example2
# 下载nginx源码包,作为案例素材
curl https://nginx.org/download/nginx-1.21.6.tar.gz > ./nginx-1.21.6.tar.gz
# 下载app代码
git clone https://gitee.com/nickdemo/helloworld
# ./nginx*
# helloworld

 2. 没有什么作用的上下文

FROM golang
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
# 仅指定镜像元数据内容
LABEL hello 1.0.0
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
# 调整为不同的上下文,查看不同的效果
docker build -t hello:1.0.0 -f Dockerfile .

3. 上下文的真正作用

FROM golang:1.18
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
LABEL hello 1.0.0
COPY ./helloworld /go/src/helloworld
WORKDIR /go/src/helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
docker build -t hello:1.0.0 -f Dockerfile .

操作:
1. 尝试在.dockerignore 文件中忽略不同的内容,观察发送到守护进程的数据 
2. 尝试 采用不同的上下文路径来构建镜像
3. 尝试 copy上下文以外的内容来构建镜像

多阶段构建

Docker 17.05版本以后,新增了Dockerfile多阶段构建。所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个 FROM 指令。这样做有什么意义呢? 多个 FROM 指令的意义 多个 FROM 指令并不是为了生成多根的层关系,最后生成的镜像,仍以最后一条 FROM 为准,之前的 FROM 会被抛弃,那么之前的FROM 又有什么意义呢? 每一条 FROM 指令都是一个构建阶段,多条 FROM 就是多阶段构建,虽然最后生成的镜像只能是最后 一个阶段的结果,但是,能够将前置阶段中的文件拷贝到后边的阶段中,这就是多阶段构建的最大意义。 最大的使用场景是将编译环境和运行环境分离,比如,之前我们需要构建一个Go语言程序,那么就需要用到go命令等编译环境

ADD 与 COPY

1. ADD 与 COPY 不能拷贝上下文以外的文件
2. COPY 命令语法格式 

COPY <src> <dest> //将上下文中源文件,拷贝到目标文件
COPY prefix* /destDir/ //将所有prefix 开头的文件拷贝到 destDir 目录下
COPY prefix?.log /destDir/ //支持单个占位符,例如 : prefix1.log、prefix2.log 等

3. 对于目录而言,COPY 和 ADD 命令具有相同的特点:只复制目录中的内容而不包含目录自身

COPY srcDir /destDir/ //只会将源文件夹srcDir下的文件拷贝到 destDir 目录下

4. COPY 区别于ADD在于Dockerfile中使用multi-stage
5. ADD 命令语法

ADD <src> <dest>

ADD 命令除了不能用在 multistage 的场景下,ADD 命令可以完成 COPY 命令的所有功能,并且还可以 完成两类的功能:
a.解压压缩文件并把它们添加到镜像中,对于宿主机本地压缩文件,ADD命令会自动解压并添加到镜像
b.从 url 拷贝文件到镜像中,需要注意:url 所在文件如果是压缩包,ADD 命令不会自动解压缩

CMD 与 ENTRYPOINT
CMD
CMD 指令有三种格式
# shell 格式
CMD <command>
# exec格式,推荐格式
CMD ["executable","param1","param2"]
# 为ENTRYPOINT 指令提供参数
CMD ["param1","param2"]

1. CMD 指令提供容器运行时的默认值,这些默认值可以是一条指令,也可以是一些参数。
2. 一个dockerfile中可以有多条CMD指令,但只有最后一条CMD指令有效
3. CMD参数格式是在CMD指令与ENTRYPOINT指令配合时使用,CMD指令中的参数会添加到 ENTRYPOINT指令中。
4. 使用shell 和exec 格式时,命令在容器中的运行方式与RUN 指令相同。不同在于,RUN指令在构建镜像时执行命令,并生成新的镜像。
5. CMD指令在构建镜像时并不执行任何命令,而是在容器启动时默认将CMD指令作为第一条执行的命令。如果在命令行界面运行docker run 命令时指定命令参数,则会覆盖CMD指令中的命令。

ENTRYPOINT
ENTRYPOINT指令有两种格式 
# shell 格式
ENTRYPOINT <command>
# exec 格式,推荐格式
ENTRYPOINT ["executable","param1","param2"]

1. ENTRYPOINT指令和CMD指令类似,都可以让容器每次启动时执行相同的命令,但它们之间又有不 同。一个Dockerfile中可以有多条ENTRYPOINT指令,但只有最后一条ENTRYPOINT指令有效。
2. 当使用shell格式时,ENTRYPOINT指令会忽略任何CMD指令和docker run 命令的参数,并且会运 行在bin/sh -c中。
3. 推荐使用exec格式,使用此格式,docker run 传入的命令参数将会覆盖CMD指令的内容并且附加 到ENTRYPOINT指令的参数中。
4. CMD可以是参数,也可以是指令,ENTRYPOINT只能是命令;docker run 命令提供的运行命令 参数可以覆盖CMD,但不能覆盖ENTRYPOINT。
5. 可以通过docker run --entrypoint 替换容器的入口程序

build arg

1. dockerfile 预定义参数:HTTP_PROXY,http_proxy,HTTPS_PROXY,https_proxy, FTP_PROXY,ftp_proxy,NO_PROXY,no_proxy,ALL_PROXY,all_proxy。预定义参数,可直 接在dockerfile中使用,无需使用arg来声明
2.通过ARG自定义参数

FROM alpine:latest as s1
ARG wd label tag
RUN echo $wd,$label,$tag
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
LABEL $label $tag
WORKDIR $wd
COPY --from=stage0 /go/src/helloworld/app ./
EXPOSE 80
ENTRYPOINT ["./app","--param1=p1","--param2=p2"]
target与cache-from

对于多阶段构建,可以通过--target指定需要重新构建的阶段。--cache-from 可以指定一个镜像作为缓存源,当构建过程中dockerfile指令与缓存镜像源指令匹配,则直接使用缓存镜像中的镜像层,从而加快构建进程。可以将缓存镜像推送到远程注册中心,提供给不同的构建过程使用,在使用前需要先pull到本地。

onbuild

onbuild指令将指令添加到镜像中,当镜像作为另一个构建的基础镜像时,将触发这些指令执行。触发指 令将在下游构建的上下文中执行。注意:onbuild指令不会影响当前构建,但会影响下游构建

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【从0配置JAVA项目相关环境1】jdk + VSCode运行java + mysql + Navicat + 数据库本地化 + 启动java项目

从0配置JAVA项目相关环境 写在最前面一、安装Java的jdk环境1. 下载jdk2. 配置jdk3. 配置环境变量 二、在vscode中配置java运行环境1. 下载VSCode2. 下载并运行「Java Extension Pack」 三、安装mysql1.官网下载MySQL2.开始安装如果没有跳过安装成功 3.配置MySQL Server4.环境变…

史上最全,资深老鸟整理-性能测试面试题汇总

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、什么是负载测试…

git 分支的创建与删除

一 创建本地分支 git checkout -b codetwo //创建本地分支 codetwo git branch newcode //创建本地分支newcode创建的分支如下图&#xff1a; 用checkout的方式创建&#xff0c;只是创建的同时还切换到了这个本地分支 二 创建远程分支 git branch newcode //创…

【开源】基于JAVA语言的木马文件检测系统

项目编号&#xff1a; S 041 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S041&#xff0c;文末获取源码。} 项目编号&#xff1a;S041&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 木马分类模块2.3 木…

一次整活,暴涨1100万播放!B站内容风向吹到哪了?

高能整活&#xff0c;千万曝光 “我准备打造一个钢铁的地下安全屋。” B站UP主手工耿近期整了一个大活&#xff0c;脑洞大到让B站用户不停地惊掉下巴。 UP主手工耿在B站拥有776.7万粉丝&#xff0c;一直以来以制造一些“看起来没用”的电焊工艺产品为内容看点&#xff0c;灵…

IO多路复用(新)

1.前景回顾 无论是阻塞IO还是非阻塞IO&#xff0c;用户应用在一阶段都需要调用recvfrom来获取数据&#xff0c;差别在于无数据时的处理方案&#xff1a; 如果调用recvfrom时&#xff0c;恰好内核没有数据&#xff0c;那么阻塞IO会使用户进程阻塞&#xff0c;非阻塞IO使CPU进行空…

C语言面试之旅:掌握基础,探索深度(面试实战之单片机——IO)

梦想和自由一样&#xff0c;都有代价&#xff0c;但都值得。 ----小新 引言 单片机是一种微控制器&#xff0c;它包含一个处理器、存储器、定时器和I/O端口等。I/O端口是单片机与外部设备进行通信的接口。通过I/O端口&#xff0c;外部设备可以输入和输出数据到单片机中。 在单…

华为对优秀项目经理的三点要求

大家好&#xff0c;我是老原。 一位优秀的项目经理应该肩负什么样的职责和使命&#xff1f; 华为轮值董事长徐直军在《致研发全体PL的一封信》中表示&#xff1a;Project Leader&#xff08;项目经理&#xff09;要从一个独立贡献者转变成为团队贡献者&#xff0c;项目经理带…

【从零认识ECS云服务器 | 快速上线个人网站】二、使用ECS云服务器

第二章 使用ECS 2.1 获取ECS 方式一&#xff1a;通过试用中心免费领取ECS实例 满足以下全部条件的阿里云用户&#xff0c;可免费试用云服务器ECS&#xff1a; 阿里云注册会员用户并完成阿里云企业认证或个人认证用户。申请用户是云服务器ECS产品的新用户&#xff0c;可以申…

电源滤波器如何检测?ATECLOUD-POWER电源自动测试软件如何助力?

电源滤波器常用来对电源中的纹波和干扰信号进行滤波&#xff0c;从而确保元器件不受损坏&#xff0c;是保证系统稳定性的重要方法。因此电源滤波器测试是非常重要的&#xff0c;通过检测来评估其质量、性能和稳定性&#xff0c;从而使电源滤波器可以稳定工作&#xff0c;进行滤…

UniApp H5 跨域代理配置并使用(配置manifest.json、vue.config.js)

UniApp 运行到浏览器的时候&#xff0c;接口会跨域报错&#xff0c;这里通过两种方式解决&#xff0c;第一&#xff1a;修改Uniapp自带的manifest.json 源码视图并进行配置h5设置。第二&#xff1a;在项目根目录新建vue.config.js并配置代理。 二选一即可。 修改或调整配置文件…

[实践总结] Java中读取properties配置文件

读取此key.properties文件 代码实现 import java.io.IOException; import java.io.InputStream; import java.util.Properties;public class PropertyUtils {private static final Properties properties new Properties();static {try (InputStream resourceAsStream Prope…

React--引入第三方插件时,标签名是小写报错问题

报错信息 报错原因 1.组件名得大写 2.缺少 import 语句 解决方案 declare global{namespace JSX{interface IntrinsicElements {micro-app: any}} }

istio为什么能代替传统的SpringCloud 服务网格Istio概述

服务网格Istio概述 什么是服务网格(Service Mesh)&#xff1f;istio简介边车模式&#xff08;Sidecar&#xff09;为什么istio能代替传统SpringCloud&#xff1f;整体架构 首先奉上 istio官网 什么是服务网格(Service Mesh)&#xff1f; 服务网格详解 服务网格&#xff08;Se…

SL4010升压恒压控制器芯片 2.5V启动 最大10A电流 支持300W大功率

SL4010是一款升压恒压控制器芯片&#xff0c;它具有2.5V启动、最大10A电流、支持300W大功率等特点。该芯片采用先进的控制技术&#xff0c;能够实现高效的电能转换&#xff0c;同时保持稳定的输出电压和电流。 SL4010芯片的主要功能是将输入的直流电压升高到所需的电压&#xf…

Http中post和get

get产生一个tcp数据包&#xff0c;服务器只响应一次&#xff0c;而post请求服务器会响应两次&#xff08;第一次发送请求头响应100&#xff0c;再次响应返回200&#xff0c;成功

配置主机与外网时间服务器同步时间

目录 NTP服务简介 时间管理命令 第一步&#xff1a;更改当前主机所在地的时间 方法一&#xff1a;使用tzselect命令查询需要的时区 1、使用tzselect命令查询需要的时区 2、添加变量到 ~/.bash_profile 文件中&#xff0c;即追加类似的内容&#xff1a; 3、重新连接一个…

HashMap系列-放入元素的流程

1.put public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {//通过key生成hash后&#xff0c;调用putVal方法public V put(K key, V value) {return putVal(hash(key), key, value, false, true);} } 2.put…

【沐风老师】3DMAX切片工具插件安装使用方法详解

3DMAX切片工具安装使用方法 3DMAX切片工具&#xff0c;该工具沿世界坐标轴以规则的间隔对对象进行切片处理。例如&#xff0c;对于快速均匀细分复杂网格、顶点绘制或应用“弯曲”修改器非常有用。 【适用版本】 3dMax2016 - 2023&#xff08;不仅限于此范围&#xff09; 【安装…

【MATLAB源码-第96期】基于simulink的光伏逆变器仿真,光伏,boost,逆变器(IGBT)。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 光伏单元&#xff08;PV Cell&#xff09; 工作原理&#xff1a;光伏单元通过光电效应将太阳光转换为直流电。它们的输出取决于光照强度、单元温度和负载条件。Simulink建模&#xff1a;在Simulink中&#xff0c;光伏单元…