Docker学习笔记05

176 阅读3分钟

这是我参与8月更文挑战的第5天,活动详情查看:  8月更文挑战

Dockerfile

1. Dockerfile是什么?

  • Dockerfile是用来构建docker镜像的文件!命令参数文件!

  • Dockerfile构建步骤

    1. 编写一个dockerfile文件
    2. docker build 构建成为一个镜像
    3. docker run 运行镜像
    4. docker push 发布镜像(DockerHub、阿里云镜像)

2. Dockerfile构建过程

  1. 基础知识

    1、每个保留关键字(指令)都必须是大写字母

    2、指令从上到下顺序执行

    3、# 表示注释

    4、每个指令都会创建一个新的镜像层,并提交!

  2. 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>不存在,则在其路径中创建所有丢失的目录

      1. Dockerfile 应至少指定CMD或ENTRYPOINT命令之一。
      2. ENTRYPOINT 应在将容器用作可执行文件时进行定义。
      3. CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行临时命令的一种方式。
      4. 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

本文摘抄或总结其他笔记,笔记不涉及任何商业用途,如果侵权请及时联系处理