【云原生|Docker】06-dokcerfile详解
目录
前言
Dockerfile基础示例
Dockerfile简介
1. Dockerfile概念
2. Dokcer镜像分层理解
3. Doker build构建原理
Dockerfile参数解析
1. Dokcerfile组成
2. 指令说明
2.1 FROM引入基础镜像
2.2 LABEL
2.3 ENV
2.4 RUN
2.5 COPY
2.6 ADD
2.7 VOLUME
2.8 EXPOSE
2.9 WORKDIR
2.10 USER
2.11 CMD
2.12 ENTRYPOINT
2.13 HEALTHCHECK
2.14 ONBUILD
Docker镜像上下文
前言
上一章我们介绍了镜像的基础操作和如何使用docker commit的方式来制作一个镜像,从我们制作openssh的镜像过程可以看出commit的方式显然不是最优的,然而docker官方给我们推荐dockerfile才是我们工作中最常用的镜像制作方式。这篇文章我们将详细介绍dockerfile的使用。
Dockerfile基础示例
还是以centos:7为基础构建一个openssh的镜像。
[root@clinet openssh]# tree .
.
├── Dockerfile
└── keys├── ssh_host_ecdsa_key├── ssh_host_ed25519_key└── ssh_host_rsa_key
[root@clinet openssh]#
[root@clinet openssh]#
FROM centos:7
LABEL name=xiaohaizhou maile=xiaohaizhou2018@163.com
RUN yum install openssh-server -y
ADD ./keys/ssh_host_ecdsa_key /etc/ssh/
ADD ./keys/ssh_host_ed25519_key /etc/ssh/
ADD ./keys/ssh_host_rsa_key /etc/ssh/
RUN chown root:root /etc/ssh/ssh_host_* && chmod 0600 /etc/ssh/ssh_host_* \&& useradd -s /bin/bash -m -d /home/xhz xhz && \echo 'xhz123'|passwd xhz --stdin
EXPOSE 22
CMD [ "/usr/sbin/sshd","-D" ]
[root@clinet openssh]#
生成镜像:
[root@clinet openssh]#docker build -t openssh:v2.1 . (注意后面有个点)
[root@clinet openssh]# docker build -t openssh:v2.1 .
[+] Building 0.0s (11/11) FINISHED => [internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 564B 0.0s=> [internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [internal] load metadata for docker.io/library/centos:7 0.0s=> [1/6] FROM docker.io/library/centos:7 0.0s=> [internal] load build context 0.0s=> => transferring context: 395B 0.0s=> CACHED [2/6] RUN yum install openssh-server -y 0.0s=> CACHED [3/6] ADD ./keys/ssh_host_ecdsa_key /etc/ssh/ 0.0s=> CACHED [4/6] ADD ./keys/ssh_host_ed25519_key /etc/ssh/ 0.0s=> CACHED [5/6] ADD ./keys/ssh_host_rsa_key /etc/ssh/ 0.0s=> CACHED [6/6] RUN chown root:root /etc/ssh/ssh_host_* && chmod 0600 /etc/ssh/ssh_host_* && useradd -s /bin/bash -m -d /home/xhz xhz && echo 'xhz123 0.0s=> exporting to image 0.0s=> => exporting layers 0.0s=> => writing image sha256:9504798a1c2921cfb8f5e3921418c81f99e31b73891235e6717c644ba9a39d8b 0.0s=> => naming to docker.io/library/openssh:v2.1 0.0s
[root@clinet openssh]#
启动镜像验证:
[root@clinet openssh]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4cb72b73e887 openssh:v2.1 "/usr/sbin/sshd -D" 17 minutes ago Up 17 minutes 22/tcp frosty_panini
[root@clinet openssh]#
[root@clinet openssh]#
[root@clinet openssh]# ssh xhz@172.17.0.2
xhz@172.17.0.2's password:
Last login: Sat Mar 25 02:55:08 2023 from gateway
[xhz@4cb72b73e887 ~]$
Dockerfile简介
1. Dockerfile概念
Dockerfile是一种文本文件,它包含了一系列用于构建Docker镜像的指令和参数。Dockerfile提供了一种声明式的方式来定义Docker镜像的构建过程,它可以用来自动化构建Docker镜像,减少手动操作的错误,快速重现镜像,方便部署和运行应用程序。
每一条指令构建一层镜像,因此每一条指令的内容,就是描述该层镜像应当如何构建。
2. Dokcer镜像分层理解
Docker镜像是分层的,这是因为Docker的镜像构建过程是基于联合文件系统(Union File System)的。
联合文件系统是一种文件系统的组合,它能够将多个不同的文件系统合并成为一个虚拟的文件系统,使得这些文件系统上的文件和目录都能够在同一个层次结构下被访问到。在Docker中,每一层镜像都是基于上一层镜像的修改而来,这些修改可以是添加、删除、修改文件等操作。当镜像被构建完成后,所有的这些修改都会被保存为一个新的层,并且每个层都是只读的。
这种分层的设计使得Docker镜像具有以下优势:
节省存储空间:因为每个层都是只读的,所以多个镜像可以共享相同的层,从而减少存储空间的使用。
提高构建速度:如果镜像已经存在于本地,那么Docker可以直接使用这些层来构建新的镜像,从而避免重新下载或构建相同的层,提高了构建速度。
提高可维护性:由于镜像的每个层都是只读的,所以可以更加方便地管理和维护镜像。
3. Doker build构建原理
当执行docker build命令时,Docker引擎会读取Dockerfile文件,并按照其中的指令逐步构建镜像。具体来说,Docker引擎会执行以下步骤:
从基础镜像开始构建:Dockerfile中的第一条指令是通常是FROM指令,用于指定基础镜像。Docker引擎会在本地或者远程仓库中查找该镜像,并在此基础上构建新的镜像。
逐条执行Dockerfile中的指令:Dockerfile中的每一条指令都会生成一个新的中间镜像,该镜像包含了该指令所描述的文件系统更改。Docker引擎会在前一条指令生成的中间镜像的基础上应用该指令,生成新的中间镜像。
最终生成镜像:当Dockerfile中的所有指令都执行完成后,Docker引擎会生成一个最终的镜像,该镜像包含了所有指令所描述的文件系统更改。
缓存机制:在执行每条指令时,Docker引擎会将其结果缓存起来。如果后续执行的指令与前面的指令没有改变文件系统,则Docker引擎会直接使用缓存中的结果,从而提高构建效率。
总的来说,Docker build的工作原理就是根据Dockerfile文件中的指令逐步构建一个新的Docker镜像,该过程中利用缓存机制提高构建效率。
Dockerfile参数解析
1. Dokcerfile组成
Dockerfile分为四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作指令
- 容器启动时执行指令
2. 指令说明
2.1 FROM引入基础镜像
第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一次)
格式:FROM <image>FROM <image>:<tag>FROM <image>@<digest>示例: FROM centos:7
注:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
2.2 LABEL
LABEL
指令用于为 Docker 镜像添加元数据,包括作者、版本、描述等信息。
LABEL
指令可以让用户更容易地了解一个 Docker 镜像的基本信息,也方便了在使用 Docker 时对镜像进行搜索和分类。(在早期的dockerfile中使用的是MAINTAINE,目前该指令已经弃用)
格式:LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:LABEL name='xiaohaizhou' mail='xiaohaizhou2018@163.com'
注:使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
2.3 ENV
ENV
指令用于设置环境变量,这些变量可以在 Docker 容器中使用。
在 Dockerfile 中使用 ENV
指令可以帮助我们在构建镜像时动态地设置一些环境变量,以适应不同的部署环境。比如,我们可以设置数据库的连接字符串、服务器的主机名、日志文件的路径等。
使用 ENV
指令可以方便地将容器的配置信息和应用程序的代码分离开来,使得应用程序的可移植性更强,同时也方便了容器的维护和部署。
格式:#<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量ENV <key> <value> #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行#ENV <key1>=<value1> <key2>=<value2> ...示例:ENV TZ "Asia/Shanghai"ENV TERM xterm
ENV k1=v1 k2=v2
2.4 RUN
Dockerfile 中的 RUN
指令用于在 Docker 镜像中执行命令或脚本。使用 RUN
指令可以在 Docker 镜像构建过程中自动化地执行一些操作,比如安装软件包、配置环境变量、创建用户等。
RUN
指令可以执行任何可以在 Linux 终端中执行的命令或脚本,如 apt-get
、yum
、pip
、git clone
、curl
等等。
注意,每个
RUN
指令都会在 Docker 镜像中创建一个新的中间层镜像,这些中间层镜像可以被后续的指令使用,但也会增加镜像的大小。因此,我们应该尽可能地将多个命令合并为一个RUN
指令,以减少中间层镜像的数量和镜像的大小。
格式:# 前者将在shell终端中运行命令,即/bin/sh -c;后者使用exec执行。每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时,可以使用\来换行。(为了方便我们经常只使用第一种方式)RUN <command>RUN ["executable","param1","param2"]示例:RUN apt-get update && apt-get install -y curlRUN curl -sL https://deb.nodesource.com/setup_14.x | bash -RUN apt-get install -y nodejs
2.5 COPY
COPY
指令用于将本地文件或目录复制到 Docker 镜像中。使用 COPY
指令可以将需要的文件或目录添加到 Docker 镜像中,以供容器在运行时使用。
COPY 指令将从构建上下文目录中 <src>
的文件或目录复制到新的一层的镜像内的 <dest>
位置。<src>
可以是多个,甚至可以是通配符,其通配符规则需要满足golang的filepath.Match规则。
<dest>
可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。
此外,还需要注意一点,使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git 进行管理的时候。
注意:
COPY
指令只能复制本地的文件或目录到 Docker 镜像中,不能复制网络上的文件。如果需要从网络中下载文件并复制到 Docker 镜像中,可以使用RUN
指令执行curl
或wget
命令下载文件,然后再使用COPY
指令将下载好的文件复制到 Docker 镜像中。
格式:#--chown=<user>:<group> 是可选参数,用于指定复制的文件或目录的用户和组,<src> 是要复制的本地文件或目录的路径,<dest> 是要复制到 Docker 镜像中的路径。COPY [--chown=<user>:<group>] <src>... <dest>示例:COPY package.json /usr/src/app/COPY hom* /mydir/COPY hom?.txt /mydir/
2.6 ADD
ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。
<src>
可以是一个 URL,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <dest>
去。下载后的文件权限自动设置为 600,如果这并不是想要的权限,那么还需要增加额外的一层 RUN 进行权限调整,另外,如果下载的是个压缩包,需要解压缩,也一样还需要额外的一层 RUN 指令进行解压缩。所以不如直接使用 RUN 指令,然后使用 wget 或者 curl 工具下载,处理权限、解压缩、然后清理无用文件更合理。因此,这个功能其实并不实用,而且不推荐使用。
<src>
为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <dest>
去。如果我们真的是希望复制个压缩文件进去,而不解压缩,这时就不可以使用 ADD 命令。在docker官方的最佳实践中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是需要自动解压缩的场合。
格式:# --chown=<user>:<group> 是可选参数,用于指定复制的文件或目录的用户和组,<src> 是要复制的本地文件或目录的路径,<dest> 是要复制到 Docker 镜像中的路径。ADD [--chown=<user>:<group>] <src>... <dest>示例:ADD https://example.com/hello.tar.gz /appADD test.tar.gz /app
2.7 VOLUME
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。相当于容器启动时使用的-v选项,只不过这里不能指定挂载到宿主机的位置。
格式:VOLUME </path/to/dir>VOLUME ["<path1>", "<path2>"...]示例:VOLUME /myvolumeVOLUME ['/data']
2.8 EXPOSE
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
比如:像上面我们创建的openssh的dockerfile中我们可以通过expose来声明80端口,但是实际上80端口并不会开启,我们也不能通过80端口来进行远程访问。
格式:EXPOSE <port> [<port>...]示例:EXPOSE 80 443 EXPOSE 11211/tcp 11211/udp
2.9 WORKDIR
使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。
格式:WORKDIR /path/to/workdir示例:# 最终路径为/a/b/cWORKDIR /aWORKDIR bWORKDIR c
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
2.10 USER
USER 指令和WORKDIR相似,都是改变环境状态并影响以后的层。WORKDIR是改变工作目录,USER则是改变之后层的执行RUN, CMD 以及ENTRYPOINT这类命令的身份。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户。
格式: USER <username>示例: USER www注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。
2.11 CMD
Docker不是虚拟机,事实上容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD 指令就是用于指定默认的容器主进程的启动命令的。
在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如ubuntu镜像默认的CMD是 /bin/bash,如果我们直接 docker run -it ubuntu 的话,会直接进入bash。我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release。这就是用 cat /etc/os-release 命令替换了默认的 /bin/bash 命令了,输出了系统版本信息。
在指令格式上,一般推荐使用exec方式执行,这类格式在解析时会被解析为JSON数组,因此一定要使用双引号 ",而不要使用单引号。
格式:CMD ["executable","param1","param2"] #使用exec执行,推荐的方式CMD command param1 param2 #在/bin/sh中执行,提供给需要交互的应用CMD ["param1","param2"] #提供给ENTRYPOINT的默认参数示例:CMD ["/usr/sbin/sshd","-D"]
如果使用/bin/shy方式执行的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如
CMD echo $HOME
在实际执行中,会将其变更为:
CMD [ "sh", "-c", "echo $HOME" ]
注意:每个Dockerfile只能有一条CMD命令。如果指定了多条,只有最后一条会被执行。
2.12 ENTRYPOINT
ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式。
ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数。ENTRYPOINT 在运行时也可以替代,不过比 CMD 要略显繁琐,需要通过 docker run 的参数 --entrypoint来指定。
当指定了ENTRYPOINT后,CMD的含义就发生了改变,不再是直接的运行其命令,而是将CMD的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:
<ENTRYPOINT> "<CMD>"
格式:ENTRYPOINT ["executable","param1","param2"]ENTRYPOINT command param1 param2 (shell中执行)示例:ENTRYPOINT ["ls", "/usr/local"]CMD ["/usr/local/tomcat"]
思考一下:那么有了 CMD 后,为什么还要有 ENTRYPOINT 呢?这种
<ENTRYPOINT> "<CMD>"
有什么好处呢?后面章节将会详细说说ENTRYPOINT 与CMD的区别
2.13 HEALTHCHECK
HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常,这是 Docker 1.12 引入的新指令。
在没有 HEALTHCHECK 指令前,Docker 引擎只可以通过容器内主进程是否退出来判断容器是否状态异常。很多情况下这没问题,但是如果程序进入死锁状态,或者死循环状态,应用进程并不退出,但是该容器已经无法提供服务了。在 1.12 以前,Docker 不会检测到容器的这种状态,从而不会重新调度,导致可能会有部分容器已经无法提供服务了却还在接受用户请求。
而自 1.12 之后,Docker 提供了 HEALTHCHECK 指令,通过该指令指定一行命令,用这行命令来判断容器主进程的服务状态是否还正常,从而比较真实的反应容器实际状态。
当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在 HEALTHCHECK 指令检查成功后变为 healthy,如果连续一定次数失败,则会变为 unhealthy。
HEALTHCHECK 支持下列选项:
- --interval=<duration>:定义健康检查的间隔时间,默认值为 30s。
- --timeout=<duration>:定义健康检查的超时时间,默认值为 30s。
- --start-period=<duration>:定义容器启动后的等待时间,以便在执行健康检查之前,容器有时间启动。默认值为 0s。
- --retries=<number>:定义容器未通过健康检查的重试次数,默认值为 3。
和 CMD, ENTRYPOINT 一样,HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效。
在HEALTHCHECK [options] CMD
后面的命令,格式和 ENTRYPOINT 一样,分为 shell 格式,和 exec 格式。命令的返回值决定了该次健康检查的成功与否:0:成功;1:失败;2:保留,不要使用这个值。
格式:HEALTHCHECK [options] CMD <command> #设置检查容器健康状况的命令HEALTHCHECK NONE #如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
示例:假设我们有个镜像是个最简单的 Web 服务,我们希望增加健康检查来判断其 Web 服务是否在正常工作,我们可以用 curl 来帮助判断:
# 这里我们设置了每5秒检查一次(这里为了试验所以间隔非常短,实际应该相对较长),如果健康检查命令超过3秒没响应就视为失败,并且使用 curl -fs http://localhost/ || exit 1 作为健康检查命令。FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \CMD curl -fs http://localhost/ || exit 1
为了帮助排障,健康检查命令的输出(包括 stdout 以及 stderr)都会被存储于健康状态里,可以用 docker inspect 来查看:
docker inspect web | grep jq .[].State.Health
2.14 ONBUILD
ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。所以该指令我们不常用。
格式: ONBUILD [INSTRUCTION]
示例:ONBUILD ADD . /app/srcONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:NNBUID后面跟指令,当当前的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
Docker镜像上下文
构建镜像指令:
# mysoft/centos:6.6为新生成的镜像的标签,"."为dockerfile所在路径。
docker build -t mysoft/centos:6.6 .
在上使用docker build来构建镜像的时候,在命令的最后面加了个".",我们直接解释为当前目录,即dockerfile所在的目录。其实这种表述是并不准确的。事实上这是在指定上下文路径。那么什么是上下文呢?
首先我们要理解docker build的工作原理:
docker在运行时分为Docker引擎(也就是服务端守护进程)和客户端工具。Docker引擎提供了一组REST API,被称为Docker Remote API。而docker命令这样的客户端工具,则是通过这组api与docker引擎交互,从而完成这种功能。因此,虽然表面上我们好像是在本机执行各种docker功能,但实际上,一切都是使用的远程调用形式在服务端(Docker引擎)完成。也因为这种C/S设计,让我们操作远程服务器的Docker引擎变得轻而易举。
当我们进行镜像构建的时候,并非所有的定制都会通过RUN指令完成,经常会需要将一些本地文件复制进镜像,比如通过COPY、ADD等指令。而docker build 命令构建镜像,其实并非在本地,而是在服务端,也就是Docker引擎中构建的。那么在这种C/S架构中,如何 才能让服务端获得本地文件呢?
这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径,docker build命令得知这个路径后,会将路径下的所有内容打包,然后上传给Docker引擎。这样Docker引擎收到这个上下文包后,展开就会获得构建镜像所需的所有文件。
如果在Dockerfile中这么写:
COPY ./package.json /app/
这并不是要复制执行docker build命令所在的目录下的package.json,也是不复制Dockerfile所在目录下的package.json,而是复制上下文目录中的package.json。
因此,COPY这类指令中的源文件的路径都是相对路径。这也是初学者经常会问的为什么COPY ../packeg.json /app
或者COPY /opt/xxx /app/
这种指令无法工作的原因,因为这些路径已经超出了上下文的范围,Docker引擎无法获得这些位置的文件。如果真的需要那些文件,应该将它们复制到上下文目录中去。
现在就可以理解docker build -t mysoft/centos:6.6 .
中的这个".",实际是在指定上下文的目录,docker build命令会将该目录下的内容打包交给docker引擎以帮助构建镜像。
理解构建上下文对镜像构建是很重要的,可以避免犯一些不应该的错误。比如有些初学者在发现COPY /opt/xxx /app/
不工作后,干脆将Dockerfile放到了根目录去构建。结果发现docker build执行后,在发送一个几十GB的东西,极为缓慢而且很容易构建失败。那是因为这种做法是在让docker build打包整个硬盘,这显然错误的使用方法。
一般来说,应该会将Dockerfile置于一个空目录下,如果该目录下没有所需的文件,那么应该把所需的文件复制一份过来。如果目录下有些东西确实不希望构建时传递给Docker引擎,那么可以使用和.gitignore一样的语法写一个.dockerignore,该文件是用于剔除不需要作为上下文传递给Docker引擎的文件。
那么为什么会有人误以为"."是指定Dockerfile所在目录的呢? 这是因为在默认情况下,如果不额外指定Dockerfile的话,会将上下文目录下的名为Dockerfile的文件作为Dockerfile。这只是默认行为,实际上Dockerfile的文件名并不要求必须为Dockerfile,并且并不要求必须位于上下文目录中,比如可以使用-f ../Dockerfile.py
参数指定某个文件为Dockerfile。当然一般大家习惯性的会使用默认的文件名Dockerfile,以及会将其置于镜像构建上下文目录中。
总结:
我们在编写Dokcerfile的时候一般会将Dockerfile置于一个空的文件夹中,也会将制作镜像所需要传入的文件或压缩包放在Dockerfile的同级目录。build的'.'指代的上下文就是Dockerfile所在的目录,这也有效的避免了在构建时传入一些不必要的文件,导致构建镜像过大。
相关文章:
![](https://img-blog.csdnimg.cn/63aef8b9b48a4bbfadd6ffb232f4f504.png)
【云原生|Docker】06-dokcerfile详解
目录 前言 Dockerfile基础示例 Dockerfile简介 1. Dockerfile概念 2. Dokcer镜像分层理解 3. Doker build构建原理 Dockerfile参数解析 1. Dokcerfile组成 2. 指令说明 2.1 FROM引入基础镜像 2.2 LABEL 2.3 ENV 2.4 RUN 2.5 COPY 2.6 ADD 2…...
![](https://img-blog.csdnimg.cn/4582dd98194145c4950583052c6056a3.png)
【SCL】博图——先入先出排序法
使用博图SCL语言来实现先入先出排序 前言 使用SCL完成一个先入先出排序 具体要求:最先输入的一个数值,最先输出出来,下面的数自动向前填充; 注:这里可能有两种理解:一是第一个输入的第一个出来ÿ…...
![](https://img-blog.csdnimg.cn/f9b13286c21248f2821233a631e5a56d.png)
OSPF----特殊区域
目录 OSPF----特殊区域 第一大类----末梢区域(Stub Area) 完全末梢区域((Totally Stub Area) 第二大类特殊区域----非完全末梢区域(NSSA) OSPF----特殊区域 第一大类----末梢区域(Stub Area)…...
![](https://img-blog.csdnimg.cn/img_convert/f3292e3b833fb13db6848d4e0524353a.png)
JVM-类加载
1:类加载机制: 加、验、准、解、初、使、卸 加、烟、准、姐、初、湿、鞋 加载、将class 文件转化为二进制流加载 JVM 内存中并生成一个该类的Class对象验证、Class 文件的字节流中包含的信息是否符合当前虚拟机的要求准备、在方法区中分配这些变量所…...
![](https://img-blog.csdnimg.cn/579d15f6d6724a72a4abab8fc4b14aec.png)
超详细讲解C语言文件操作!!
超详细讲解C语言文件操作!!什么是文件文件名文件的打开和关闭文件指针文件的打开和关闭文件的顺序读写文件的随机读写fseekftellrewind文本文件和二进制文件文件读取结束的判定文件缓冲区什么是文件 磁盘上的文件是文件。但是在程序设计中,我…...
![](https://img-blog.csdnimg.cn/098a47ef1b9e4740aaeaccec1749d5c3.png)
linxu学习之进程
文章目录进程程序和进程产生进程销毁进程多进程高并发设计孤儿僵尸守护进程孤儿进程:守护进程(重点)僵尸进程:进程 程序和进程 操作系统可以运行多个程序,那他是如何运行的?实际上,CPU的执行是很快的,而待…...
![](https://www.ngui.cc/images/no-images.jpg)
蓝桥杯真题2
[蓝桥杯 2013 省 B] 连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在 111 ~ NNN 的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间 [L,R][L, R][L,R] 里的所有元素(即此排列的…...
![](https://img-blog.csdnimg.cn/7bf2969b4e3d4aae8813ec8500c3e4db.png)
PWM互补输出,以及死区时间计算
本文基于野火例程进行解说 实验内容 本次实验输出一对互补的pwm波,且进行死区时间的计算说明。 代码 互补输出对应的定时器初始化代码: bsp_advance_tim.c /********************************************************************************* fi…...
![](https://img-blog.csdnimg.cn/ec23144f0aea4f2b9f131c58c69ea025.png#pic_center)
基于深度学习的海洋动物检测系统(Python+YOLOv5+清新界面)
摘要:基于深度学习的海洋动物检测系统使用深度学习技术检测常见海洋动物,识别图片、视频和实时视频中的海洋动物,方便记录、展示和保存结果。本文详细介绍海洋动物检测系统,在介绍算法原理的同时,给出Python的实现代码…...
![](https://www.ngui.cc/images/no-images.jpg)
C# 计算方差
50,100,100,60,50 计算他们的方差 为了计算这些数的方差,需要进行以下步骤: 1. 计算平均值,即将这些数相加,然后除以它们的数量。 平均值 (50 100 100 60 50) / 5 72 2. 计…...
![](https://img-blog.csdnimg.cn/241f9c6f13ff44c896ec00fbfbd2baf2.jpeg#pic_center)
HJZS电源监视继电器HJZS-E202 AC220V
系列型号: HJZS-E202断电延时继电器 HJZS-E002断电延时继电器 一 应用 HJZS-E202电源监视继电器用于直流或交流操作的各种保护和自动控制的装置中,用以增加触点数量。 二 安装结构 导轨安装9壳体结构,具体尺寸参阅外型尺寸图。 三 产品型号…...
![](https://img-blog.csdnimg.cn/28c09ee3d337427ca379b39b5158f2ed.png)
dolphinscheduler 2.0.6 资源中心改造方案二:通过NFS挂载共享目录
目录调度资源中心存储概要安装NFS服务器客户端调度验证关闭SFTP开关(可忽略)重新上传资源文件worker执行任务验证服务器woker客户端worker其它nfs共享目录的配置文件/etc/exports说明调度资源中心存储概要 针对现有的单机存储可以做哪些扩展?…...
![](https://img-blog.csdnimg.cn/img_convert/f6e1681a7eef6fd21327a1161700fc19.png)
基于集成学习的用户流失预测并利用shap进行特征解释
基于集成学习的用户流失预测并利用shap进行特征解释 小P:小H,如果我只想尽可能的提高准确率,有什么好的办法吗? 小H:优化数据、调参侠、集成学习都可以啊 小P:什么是集成学习啊,听起来就很厉害的…...
![](https://img-blog.csdnimg.cn/745bd5b48e3e423b8076b41c139fe882.png)
【Java版oj 】 day17杨辉三角形的变形、计算某字符出现次数
目录 一、杨辉三角形的变形 (1)原题再现 (2)问题分析 (3)完整代码 二、计算某字符出现次数 (1)原题再现 (2)问题分析 (3)完整代…...
![](https://www.ngui.cc/images/no-images.jpg)
智能驾驶芯片赛道混战:如何看待5类玩家的竞争格局?
智能驾驶芯片赛道,一直是业内关注的焦点。 高工智能汽车注意到,针对L0-L2,业内基本采用智能前视一体机(IFC)方案;要实现高速NOA、城市NOA等更为高阶的智驾功能等,则基本采用域控制器方案。从IF…...
![](https://img-blog.csdnimg.cn/a02b0a2c51f34d9bafe8754d275ead74.gif)
vue antd table表格的增删改查(三)input输入框根据关键字模糊查询【后台管理系统 使用filter与indexOf嵌套】
vue antd table表格的增删改查(三)input输入框根据关键字查询【后台管理系统filter与indexOf嵌套】知识回调场景复现利用filter和indexOf方法实现模糊查询1.查询对象为单层的数组元素2.查询对象为多层的数组元素(两层为例)3.查询对…...
![](https://www.ngui.cc/images/no-images.jpg)
【计组】性能指标——速度
衡量计算机性能的指标之一——速度,是指计算机执行完所有指令所耗费时间的长短。 一、概念: 引出了如下概念:机器字长:指计算机一次能处理的二进制位数,也就是我们通常说的32位64位计算机中的位。 机器字长决定了计算…...
![](https://img-blog.csdnimg.cn/img_convert/1209af6294fb41159d483ede5627fe41.png)
【PC自动化测试-4】inspect.exe 详解
1,inspect.exe图解" 检查 "窗口有几个主要部分:● 标题栏。 显示" 检查 HWND (窗口句柄) 。● 菜单栏。 提供对 检查功能 的访问权限。● 工具 栏。 提供对 检查功能 的访问权限。● 树视图。 将 UI 元素的层次结构呈现为树视图控件&…...
![](https://img-blog.csdnimg.cn/0c9ad849be744245a20c61f693445384.png)
比肩ChatGPT的国产AI:文心一言——有话说
🔗 运行环境:chatGPT,文心一言 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好&am…...
![](https://www.ngui.cc/images/no-images.jpg)
【第13届蓝桥杯】C/C++组B组省赛题目+详解
A.九进制转十进制 题目描述 九进制正整数(2022)9转换成十进制等于多少? 解: 2*9^02*9^12*9^321814581478; B.顺子日期 题目描述 小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456等。顺子日期指的就是在日期的yyyymmdd表示法中&a…...
![](https://img-blog.csdnimg.cn/img_convert/3f6c83f9dd27b6741ab31daa84aef30a.png)
STM32 KEI 调试新手注意事项
记录一下解决问题的经过:1,用STM32 cubeMX 生成的MKD工程,默认的代码优化级别是level3 , 这个级别 会把一些代码给优化掉,造成一些意想不到的结果,最直观的就是 被优化的语句不能打断点调试,当你打了断点 ,…...
![](https://img-blog.csdnimg.cn/97e5fc5cdca94f2a8210d7e3c9cd313a.png#pic_center)
Windows权限提升—令牌窃取、UAC提权、进程注入等提权
Windows权限提升—令牌窃取、UNC提权、进程注入等提权1. 前言2. at本地命令提权2.1. 适用范围2.2. 命令使用2.3. 操作步骤2.3.1. 模拟提权2.3.2. at配合msf提权2.3.2.1. 生成木马文件2.3.2.2. 设置监听2.3.2.3. 设置反弹2.3.2.4. 查看反弹效果3. sc本地命令提权3.1. 适用范围3.…...
![](https://img-blog.csdnimg.cn/9dc17463549348a8ac59c3282fc56bd6.jpeg#pic_center)
不做孔乙己也不做骆驼祥子
对教书育人的探讨前言一、为什么要“育人”1.育人为先2.育人是快乐的二、怎么“育人”前言 借着本次师德师风建设的主题,跟各位老师谈一谈对于“育人”的一些观点,和教育的一些看法。本文仅代表自己的观点,有不到位的地方,大家可以…...
![](https://img-blog.csdnimg.cn/0e1a90a39ff44180b44cd22c8576af58.png)
ChatGPT原理解析
文章目录Transformer模型结构构成组件整体流程GPT预训练微调模型GPT2GPT3局限性GPT4相关论文Transformer Transformer,这是一种仅依赖于注意力机制而不使用循环或卷积的简单模型,它简单而有效,并且在性能方面表现出色。 在时序模型中&#…...
![](https://www.ngui.cc/images/no-images.jpg)
常用算法实现【必会】:sort/bfs/dfs
文章目录常用排序算法实现(Go版本)BFS 广度优先遍历,利用queueDFS 深度优先遍历,利用stack前序遍历(根 左 右)中序遍历(左根右)后序遍历(左 右 根)BFS/DFS 总…...
![](https://img-blog.csdnimg.cn/e8fde48a027242279a4cf5e8838914a7.png)
瑟瑟发抖吧——用了这款软件,我的开发效率提升了50%
一、前言 开发中,一直听到有人讨论是否需要重复造轮子,我觉得有能力的人,轮子得造。但是往往开发周期短,用轮子所节省的时间去更好的理解业务,应用到业务中,也能清晰发现轮子的利弊,一定意义上…...
![](https://image-1305421143.cos.ap-nanjing.myqcloud.com/image/76f5c092e753e7e745fca85efc1f5106.gif)
笔记本只使用Linux是什么体验?
个人主页:董哥聊技术我是董哥,嵌入式领域新星创作者创作理念:专注分享高质量嵌入式文章,让大家读有所得!近期,也有朋友问我,笔记本只安装Linux怎么样,刚好我也借此来表达一下我的感受…...
![](https://img-blog.csdnimg.cn/img_convert/9017f9900d4c694a743e3a91b9f3f85d.png)
pipeline业务发布
业务环境介绍公司当前业务上线流程首先是通过nginx灰度,dubbo-admin操作禁用,然后发布上线主机,发布成功后,dubbo-admin启用,nginx启用主机;之前是通过手动操作,很不方便,本次优化为…...
![](https://img-blog.csdnimg.cn/0f0e9633d9254098a0d2dec0873b88fb.png#pic_center)
【巨人的肩膀】JAVA面试总结(七)
💪MyBatis 1、谈谈你对MyBatis的理解 Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以…...
![](https://img-blog.csdnimg.cn/096ff30d2b364ab3a9cccb4331c4179b.gif)
Python满屏表白代码
目录 前言 爱心界面 无限弹窗 前言 人生苦短,我用Python!又是新的一周啦,本期博主给大家带来了一个全新的作品:满屏表白代码,无限弹窗版!快快收藏起来送给她吧~ 爱心界面 def Heart(): roottk.Tk…...
![](http://pbl6hpz34.bkt.clouddn.com/1540995293104nr1ktifl.png?imageslim)
https下安装wordpress/对网站进行seo优化
资源整理。这次太久没更新,最近比较忙。老规矩拆成两篇。 Coding: 1.比较独立,部分汇集和系统发育知识的生态位模型。“Niche estimation above and below the species level. Trends in Ecology and Evolution”论文的附件。 phyloENM TREE 2.用于生态预…...
![](https://img2018.cnblogs.com/blog/1197012/201901/1197012-20190116151526255-1005624108.png)
wordpress使用html界面/搜索网页内容
1.在iis中选择物理路径。配置域名 2.添加php默认文档 3.修改处理程序映射 4.设置模块映射信息 转载于:https://www.cnblogs.com/zhangyouwu/p/10277174.html...
![](/images/no-images.jpg)
网站的营销与推广/网站收录查询工具
bitsCN.comMySQL提供标准的SQL模式匹配,以及一种基于象Unix实用程序如vi、grep和sed的扩展正则表达式模式匹配的格式。SQL的模式匹配允许你使用“_”匹配任何单个字符,而“%”匹配任意数目字符(包括零个字符)。在 MySQL中,SQL的模式缺省是忽略…...
![](https://img-blog.csdnimg.cn/20200603081856733.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE5NTYxNQ==,size_16,color_FFFFFF,t_70)
建设信用卡在网站挂失几步/seo海外推广
一、申请免费的域名 1、链接:http://www.ngrok.cc/login.html 2、注册账号及登录 3、开通隧道 注:隧道名称:brightbright属于自定义的 二、下载客户端 1、客户端下载地址:http://www.ngrok.cc 2、选择Ngrok客户端 3、根据实…...
![](https://img-blog.csdnimg.cn/img_convert/677db526d9103b74cdfe62f1fd5f8de9.png)
徐州手机网站建设公司哪家好/搜索引擎优化答案
2017 年 10 月 15 日,Kubernetes End User Conference (KEUC) 即将揭开神秘面纱。聚焦 Kubernetes 中国行业应用与技术落地,致力于为业界带来最新 Kubernetes 与容器技术和行业应用案例展示,本次大会邀请到了 Google、VMware、华为、IBM、网易…...
![](/images/no-images.jpg)
php网站外包/保定seo网站推广
题目描述: 692. 前K个高频单词 给一非空的单词列表,返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。 示例 1: 输入: [“i”, “love”, “leetcod…...