这是我参与8月更文挑战的第5天,活动详情查看: 8月更文挑战
Dockerfile
1. Dockerfile是什么?
-
Dockerfile是用来构建docker镜像的文件!命令参数文件!
-
Dockerfile构建步骤
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub、阿里云镜像)
2. Dockerfile构建过程
-
基础知识
1、每个保留关键字(指令)都必须是大写字母
2、指令从上到下顺序执行
3、# 表示注释
4、每个指令都会创建一个新的镜像层,并提交!
-
Dockerfile命令
FROM # 基础镜像,一切从这里开始构建 centos LABEL # 描述信息 RUN # 镜像构建的时候需要运行的命令 ADD # 步骤:tomcat 镜像,这个 tomcat 压缩包!添加内容 WORKDIR # 镜像的工作目录 VOLUME # 挂载的目录 EXPOSE # 暴露端口,等同于启动时的 —p CMD # 指定这个容器启动的时候需要运行的命令,只有最后一个会生效,而且可被替代 ENTRYPOINT # 指定这个容器启动的时候需要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令。触发指令! COPY # 类似 ADD ,将我们的文件拷贝到镜像中 ENV # 构建的时候设置环境变量-
DockerDockerfile按顺序运行指令。一个Dockerfile 必须以FROM开始。这可能在解析器指令、注释和全局范围的 ARG 之后。该FROM指令指定正在构建的父镜像像。FROM前面只能有一个或多个ARG指令。
-
Dockerfile 应至少指定CMD或ENTRYPOINT命令之一
-
FROM
FROM [--platform=<platform>] <image> [AS <name>] or FROM [--platform=<platform>] <image>[:<tag>] [AS <name>] or FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]- FROM必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从FROM语句开始.
- FROM可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像。或使用一个构建阶段作为另一个构建阶段的依赖项。 只需记下每个新 FROM 指令之前提交的最后一个镜像 ID 输出。 每个 FROM 指令都会清除由先前指令创建的任何状态.
- 可以选择通过将 AS 名称添加到 FROM 指令来为新构建阶段指定名称。 该名称可用于后续的 FROM 和 COPY --from=<name> 指令以引用在此阶段构建的镜像。
- tag 或 digest是可选的。 如果您省略其中任何一个,构建器默认采用最新标签。 如果找不到标签值,构建器将返回错误。
- --platform 标志可用于在 FROM 引用多平台镜像的情况下指定镜像的平台。 例如,linux/amd64、linux/arm64 或 windows/amd64。默认情况下,使用构建请求的目标平台
- FROM指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来
-
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ... # 查看镜像的标LABEL $ docker image inspect --format='' 镜像名-
要在LABEL值中包含空格,请像在命令行解析中一样使用引号和反斜杠
-
一个镜像中可以有多个标签。可以在一行中指定多个标签。
-
包含在基本镜像或父镜像(在FROM行中的镜像)中的LABEL由现在的镜像继承。如果LABEL已存在但具有不同的值,则最近应用的值会覆盖任何先前设置的值。
-
示例
# 在一条指令中指定多个标签 # 方式1 LABEL multi.label1="value1" multi.label2="value2" other="value3" # 方式2 LABEL multi.label1="value1" \ multi.label2="value2" \ other="value3" LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines."
-
-
CMD
CMD ["executable","param1","param2"] # execform,这是首选形式 or CMD ["param1","param2"] # 作为ENTRYPOINT 的默认参数 or CMD command param1 param2 # shellform- CMD指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效
- CMD的目的是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。
- CMD会在启动容器的时候执行,build 时不执行,而RUN只是在构建镜像的时候执行,后续镜像构建完成之后,启动容器就与RUN无关了。
-
ADD
ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] # 包含空格的路径-
该--chown功能仅在用于构建 Linux 容器的 Dockerfile 上受支持,不适用于 Windows 容器。
-
ADD复制本地主机文件、目录或者远程文件 并且添加到容器指定路径中
-
可以指定多个 <src> 资源,但如果它们是文件或目录,则它们的路径被解释为相对于构建上下文的源。
-
每个 <src> 可能包含通配符,匹配将使用 Go 的 filepath.Match 规则完成
-
<src> 路径必须在构建的上下文中
-
<src>
- 如果 <src> 是一个 URL 并且 <dest> 不以斜杠结尾,那么文件将从 URL 下载并复制到 <dest>
- 如果 <src> 是一个 URL 并且 <dest> 以斜杠结尾,则从 URL 推断文件名并将文件下载到 <dest>/<filename>
- 如果<src>是目录,则复制目录的全部内容,包括文件系统元数据。不会复制目录本身,只会复制其内容
- 如果 <src> 是采用可识别压缩格式(identity、gzip、bzip2 或 xz)的本地 tar 存档,则将其解压缩为目录。 来自远程 URL 的资源不会被解压缩。
- 如果<src>是任何其他类型的文件,则将其与其元数据一起单独复制。在这种情况下,如果<dest>以斜杠结尾/,它将被视为一个目录,其内容<src>将被写入<dest>/base(<src>)
- 如果直接指定了多个资源,或者由于使用了通配符,则<dest>必须是目录,并且必须以斜杠结尾/
-
<dest>
-
如果<dest>不以斜杠结尾,则将其视为常规文件,并将其内容<src>写入<dest>.
-
如果<dest>不存在,则在其路径中创建所有丢失的目录
-
- Dockerfile 应至少指定CMD或ENTRYPOINT命令之一。
- ENTRYPOINT 应在将容器用作可执行文件时进行定义。
- CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行临时命令的一种方式。
- CMD 使用替代参数运行容器时将被覆盖。
-
-
EXPOSE
EXPOSE <port> [<port>/<protocol>...]- 通知 Docker 容器在运行时监听指定的网络端口。 可以指定端口是监听TCP还是UDP,如果不指定协议,默认为TCP。
- EXPOSE 指令实际上并不发布端口。 它充当构建镜像者和运行容器的人之间的一种文档
- 要在运行容器时实际发布端口,在 docker run 上使用-p或者-P选项生效
-
ENV
ENV <key> <value> # 只能设置一个变量 ENV <key>=<value> ... # 允许一次设置多个变量-
指定一个环境变量,会被后续RUN指令使用,并在容器运行时保留
-
示例
ENV MY_NAME "John Doe" ENV MY_DOG Rex The Dog ENV MY_CAT fluffy ENV myName="John Doe" myDog=Rex\ The\ Dog \ myCat=fluffy
-
-
COPY
COPY [--chown=<user>:<group>] <src>... <dest> or COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] # 包含空格的路径-
--chown功能仅在用于构建 Linux 容器的 Dockerfile 上受支持,不适用于 Windows 容器
-
COPY 指令从 <src> 复制新文件或目录,并将它们添加到容器的文件系统中 <dest> 路径
-
可以指定多个 <src> 资源,但文件和目录的路径将被解释为相对于构建上下文的源
-
每个 <src> 可能包含通配符,匹配将使用 Go 的 filepath.Match 规则完成
-
<dest> 是绝对路径,或相对于 WORKDIR 的路径,源将在目标容器内复制到该路径中。
-
<src>
- <src> 路径必须在构建的上下文中
- 如果\src>是目录,则复制目录的全部内容,包括文件系统元数据。不会复制目录本身,只会复制其内容
- 如果<src>是任何其他类型的文件,则将其与其元数据一起单独复制。在这种情况下,如果<dest>以斜杠结尾/,它将被视为一个目录,其内容<src>将被写入<dest>/base(<src>)
- 如果指定了多个 <src> 资源,无论是直接指定还是由于使用了通配符,则 <dest> 必须是目录,并且必须以斜杠 / 结尾
-
<dest>
- 如果 <dest> 不以斜杠结尾,它将被视为一个普通文件,<src> 的内容将写入 <dest>
- 如果 <dest> 不存在,它会与路径中所有缺失的目录一起创建
-
-
ENTRYPOINT
ENTRYPOINT ["executable", "param1", "param2"] # execform ENTRYPOINT command param1 param2 # shellform- 配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,而CMD是可以被覆盖的。如果需要覆盖,则可以使用docker run --entrypoint选项。
- 每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效
-
VOLUME
# 创建一个具有指定名称的挂载点,并将其标记为保存来自本机主机或其他容器的外部挂载卷 VOLUME ["/data"]-
基于 Windows 的容器上的卷:使用基于 Windows 的容器时,容器内卷的目标必须是以下之一:
- 一个不存在或空的目录
- 驱动器以外的驱动器
C:
-
从 Dockerfile 中更改卷:如果任何构建步骤在声明卷后更改了卷中的数据,则这些更改将被丢弃。
-
JSON 格式:列表被解析为 JSON 数组。您必须用双引号 (
") 而不是单引号 (')将单词括起来。 -
主机目录在容器运行时声明:主机目录(挂载点)本质上是依赖于主机的。这是为了保持镜像的可移植性,因为不能保证给定的主机目录在所有主机上都可用。因此,无法从 Dockerfile 中挂载主机目录。该
VOLUME指令不支持指定host-dir参数。必须在创建或运行容器时指定挂载点。
-
-
USER
USER <user>[:<group>] or USER <UID>[:<GID>]- 指定运行容器时的用户名或 UID,后续的RUN、CMD、ENTRYPOINT也会使用指定用户
-
WORKDIR
WORKDIR /path/to/workdir- WORKDIR指令为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。
- 如果WORKDIR不存在,它将被创建,即使它没有在任何后续的Dockerfile指令中使用。
- WORKDIR 指令可以在 Dockerfile 中多次使用。 如果提供了相对路径,它将相对于前一个 WORKDIR 指令的路径
-
RUN
RUN <command> # shellform # 在 Linux 上默认为 /bin/sh -c,在 Windows 上默认为 cmd /S /C) or RUN ["executable", "param1", "param2"] # execform- 每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的 版本控制
-
3. Dockerfile Examples
FROM cento
LABEL com.example.version="0.0.1-beta"
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD /bin/bash
本文摘抄或总结其他笔记,笔记不涉及任何商业用途,如果侵权请及时联系处理