Dockerfile Reference(中文手册)

Dockerfile文件

1.作用

​ Docker可以通过读取Dockerfile文件自动构建镜像

2.构建命令docker build

2.1作用

docker build 可以根据Dockerfile文件和context来构建镜像.其中context为如下:

The build’s context is the set of files at a specified location PATH or URL.

  1. The PATH is a directory on your local filesystem.
  2. The URL is a Git repository location.
docker build . #其中.就是context中的path

Note:有的时候在context处会创建一个.dockerignore文件,来排除文件和目录

2.2.Dockerfile文件的位置
  1. 一般Dockerfile文件存在docker build context的根目录处。或者可以用docker build -f 指定Dockerfile文件位置.

    docker build -f /path/to/a/Dockerfile .
    
  2. 可以使用-t来指定生成的新镜像(new image)保存的仓库位置(a repository and tag)

    docker build -t shykes/myapp .
    
2.3.Dockerfile构建过程

在这里插入图片描述

在构建过程中存在build-cache来加速构建过程

3. BuildKit

3.1.作用

在这里插入图片描述

3.2 使用

Dockerfile利用buildKit来加速构建过程,必须要设置环境变量DOCKER_BUILDKIT=1在docker build之前

如何书写利用buildKit的Dockerfile

4.Dockerfile格式

4.1.基本格式
# Comment
INSTRUCTION arguments
  1. instruction指令不是大小写敏感的,但是常用大写来区分arguments。
  2. 在comment和Instruction的前置空格(leading whitespace)是被忽略的。
4.2.解析器指示(parser directive)和全局变量ARGs

4.2.1解析器指示:

  1. 作用:指定了Dockerfile中命令行的处理方式即bash还是shell

  2. 位置: Therefore, all parser directives must be at the very top of a Dockerfile. (即全局变量、INSTRUCTION以及注释 前)

  3. 格式: # directive=value

  4. 注意:# directive=value只能出现一次,允许在解析器指示中使用非换行空格(Non line-breaking whitespace)

  5. 具体的解析器指令即directive有syntax和escape

  6. syntax

    1. 格式:

      # syntax=[remote image reference]
      This feature is only available when using the BuildKit backend, and is ignored when using the classic builder backend.
      
    2. 作用:syntax 指示定义了Dockerfile的语法来构建该Dockerfile

    3. 其中remote image reference的Official releases

  7. escape

    1. 格式:

      # escape=\
      or 
      # escape=`
      
    2. 作用:设置Dockerfile中的转义字符,默认为反斜线即# escape=\ (backslash)

    3. 转义字符(escape character)的作用:

      1. 转义字符
      2. 衔接下一行(This allows a Dockerfile instruction to span multiple lines. ),但不会在RUN命令中执行转义,除非在行尾。
4.2.2 **ENV环境变量(environment replacement)
  1. 声明: ENV variable_name=value …

  2. 引用: $variable_name or ${variable_name}

  3. 在引用中使用bash修饰符:

    1. ${variable:-word}:如果variable设置,则结果就是设置的值;如果variable没有设置,则结果就是word
    2. ${variable:+word}:如果variable设置,则结果就是word;如果variable没有设置,则结果就是空字符串(empty string)
  4. 例子:

    FROM busybox
    ENV FOO=/bar
    WORKDIR ${FOO} #WORKDIR /bar
    ADD . $FOO     #ADD . /bar
    COPY \$FOO /quux #COPY $FOO /quux
    

在这里插入图片描述
5. 适用INSTRUCTION (This value will be in the environment for all subsequent instructions in the build stage and can be replaced inline in many as well.):

​ ADD、COPY、ENV、EXPOSE、FROM、LABELSTOPSIGNALUSERVOLUMEWORKDIR、ONBUILD

  1. 注意:

    与LABEL Instruction、ARG Instruction(关于变量设置)一样,如果key或者value字符串中没有转义字符、空格以及环境变量时,不需要用双引号括起来。
    在这里插入图片描述
    以上等价于 ENV MY_NAME=“John Doe” MY_DOG=REX\ The\ Dog MY_CAT=fluffy

4.3.** ARG
  1. 位置:ARG声明变量可以在第一个FROM指令前面,也能FROM指令后面

  2. 格式:ARG variable_name=variable_value

    ARG  CODE_VERSION=latest
    FROM base:${CODE_VERSION}
    CMD  /code/run-app
    
    FROM extras:${CODE_VERSION}
    CMD  /code/run-extras
    
  3. 注意: 由于ARG可以出现在FROM指令前面,那么该ARG设置的值不在构建阶段(一个构建阶段指的是:两个FROM之间的指令),如果在FROM指令之后进入构建阶段后想要使用FROM指令前设置的ARG变量值,则必须在构建阶段重新用ARG声明变量名但不设置值。

    ARG VERSION=latest
    
    FROM busybox:$VERSION 
    ARG VERSION
    RUN echo $VERSION>image_version
    
**ARG和ENV的区别:
  1. ARG只能使用在构建镜像过程中FROM等命令中。(构建过程)
  2. ENV可以使用构建镜像过程中和容器启动过程中,即从引入该ENV的行开始。(构建过程、运行过程)
#The environment variables set using ENV will persist when a container is run from the resulting image.
ENV DEBIAN_FRONTEND=noninteractive 

#using ARG, which is not persisted in the final image
ARG DEBIAN_FRONTEND=noninteractive  #具有自动识别的功能
RUN apt-get update && apt-get install -y ...

# Only effective in the RUN instruction
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
4.4.**FROM
  1. Dockerfile必须以FROM指令开头,但在**解析器指示(Parser directives)、注释(comment)以及全局变量ARGs后面。**FROM指明了构建新镜像的基础镜像

  2. 格式:

    FROM [--platform=<platform>] <image> [AS <name>]
    FROM [--platform=<platform>] <image>[:tag] [AS <name>]
    FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
    

    image:来自Public Repositories.的可以pull的镜像
    AS < name >:对构建过程进行命名The name can be used in subsequent FROM and COPY --from=<name> instructions to refer to the image built in this stage.

    :tag/@digest:指明基础镜像的版本号,默认latest

    –platform=< platform >:指明构建的新镜像适用的平台,选项有linux/amd64,linux/arm64,windows/amd64 (amd为桌面级处理器和桌面级GPU的厂商,而ARM为移动级处理器的生产厂商)

  3. 注意:

    1. 在一个Dockerfile文件中可以出现多个FROM指令来构建多个不同的镜像或者一个构建阶段作为另一个构建阶段的依赖。
4.5. **RUN
  1. 作用:RUN指令将会在当前镜像的顶层(创建的新层)上执行RUN后面的command,然后提交结果(commit the results)

  2. 格式:主要有两种

    1. RUN < command > :等价于在Linux系统上 /bin/sh -c ‘< command >’ ;在window系统上 cmd/S /C。 其实是可以根据自己的需要执行特定的脚本语言: (shellform)

      RUN /bin/bash -c 'source $HOME/.barhrc;\
      echo $HOME'
      1. 在RUN Instruction中可以执行多条命令commands用;间隔
      2. 在RUN Instruction中不同命令commands可以处在不同行,用规定的转义字符衔接,默认为\
      
      以上的Instruction等价于
      RUN /bin/bash -c 'source $HOME/.bashrc;echo $HOME'
      
      以上的Instruction等价于
      RUN ["/bin/bash","-c","source $HOME/.bashrc;echo $HOME"]
      
    2. RUN [“executable”,“param1”,“param2”] (execform)
      在这里插入图片描述

    在Linux系统中单引号和双引号的区别 主要区别是双引号字符串中会对特殊字符进行处理,而单引号不会对特殊字符进行处理

    因为:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4K6WhvOg-1657461351124)(Dockerfile.assets/image-20220709113441638-165733768385110.png)]

    所以:
    在这里插入图片描述

    1. 注意:

      The cache for RUN instructions isn’t invalidated automatically during the next build. The cache for an instruction like RUN apt-get dist-upgrade -y will be reused during the next build. The cache for RUN instructions can be invalidated by using the --no-cache flag, for example docker build --no-cache.

      ​ 在下一次构建过程中,关于RUN instructions的缓存不会自动失效,换句话说会用上一次RUN构建缓存结果代替重新执行命令。如果采用上一次的RUN缓存,则用docker build;否则 docker build --no-cache

4.6. **CMD
  1. 格式:

    CMD ["executable","param1","param2"] (exec form, this is the preferred form)
    CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
    CMD command param1 param2  (shell form) 默认采用的是/bin/sh -c “command”
    
  2. 作用:为启动容器时提供默认命令。等价于docker run -d xxx command

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3KHFQrcg-1657461351127)(Dockerfile.assets/image-20220709192232546-165736575340511.png)]

  1. 注意:

    1. CMD指令只能在Dockerfile中出现一次,如果出现多次则以最后一个CMD instruction为准。
    2. 在CMD指令中引用环境变量采用的是exec form,以及execform中的采用的是双引号而不是单引号。
    3. 如果用户使用docker run指定容器启动的命令则会覆盖CMD的instruction。
4.7. **CMD和RUN的区别

在这里插入图片描述

  1. RUN作用在镜像构建过程中,CMD作用在镜像封装成容器启动时。
  2. RUN的结果会影响新镜像的构建,CMD的结果会影响容器启动执行的指令。
4.8.Label
  1. 格式:

    LABEL <key>=<value> <key>=<value> <key>=<value> ......
    要在key和value中使用空格则用双引号括起来和反斜杠衔接另一行
    
  2. 作用:

    可以为生成的镜像添加元数据标签信息,这些信息可以用来辅助过滤出特定镜像,其LABEL设置的结果可以用 docker image inspect < image-name > 显示

4.9.MAINTAINER(deprecated)
  1. 作用:为生成的镜像设置作者author字段元数据,可以用LABEL替代,可以用docker inspect命令查看

  2. 格式:

    MAINTAINER <name>
    等价于
    LABEL author=<name>
    
4.10. **EXPOSE
  1. 格式:

    EXPOSE <port> [<port>/<protocol>...]
    
  2. 作用:

    EXPOSE指令通知Docker容器运行时监听的特定端口号,既可以监听TCP端口也可以是UDP端口,但默认是TCP端口.
    在这里插入图片描述
    EXPOSE并没有对主机外的网络暴露容器端口,必须要用docker run -p指定主机端口和容器端口的映射(set up port redirection on the host system)。 此时网络连接通过-p指定的主机端口映射到容器内部端口,实现容器与外部的通信.例子如下:

    EXPOSE 80/udp 
    EXPOSE 80/tcp
    
    docker run -p 80:80/tcp -p 80:80/udp ...
    此时网络可以通过host的80端口号映射到container的80端口号,使得容器中的应用与外部进行通信
    

    具体docker中的网络配置

4.11 **ADD
  1. 格式:

    ADD [--chown=<user>:<group>]<src>...<dest>
    ADD [--chown=<user>:<group>]["<src>",...,"<dest>"]
    当后一个形式的路径可以有空格、转义字符以及环境变量。
    <src>:如果是文件或者目录时,<src>路径会理解为docker build时context的相对路径.
    <dest>:是被构建镜像的文件系统的路径.可以是绝对路径或者相对于<WORKDIR>的相对路径
    --chown:指明新创建的文件在镜像中的所有权默认是UID和GID为0即root用户
    <user>:<group>:可以是用户名、群组名或者UID、GID的组合
    
  2. 作用:

    Add instruction复制新文件、新目录以及远程URL的文件< src >到该镜像文件系统的特定位置< dest >。

  3. 注意:

    1. –chown: 参数只能支持构建Linux容器的Dockerfile,不支持构建Window容器的Dockerfile

      If a username or groupname is provided, the container’s root filesystem /etc/passwd and /etc/group files will be used to perform the translation from name to integer UID or GID respectively.
      在这里插入图片描述

    2. < src >可能有通配符,匹配规则

    3. 如果URL文件存在验证保护,则需要用RUN wgetRUN curl来代替ADD


    4. < src >只能指向context内部,不能context之外

    5. if < src >是URL的规则

    1. if < src >是文件夹的规则:
      在这里插入图片描述
      < src >中指向文件夹的内容会被复制到新镜像中特定位置,但文件夹本身不会复制。

    2. if< src >是文件时:
      在这里插入图片描述

      重点:如果< src >是文件,< dest >后面没有反斜杠,则被认为对< src >文件的重命名

  4. 例子:

    ADD hom?.txt /mydir/
    把context主目录下的hom?.txt文件复制到镜像文件系统中/mydir/目录下
    
    The example below uses a relative path, and adds “test.txt” to <WORKDIR>/relativeDir/:
    ADD test.txt relativeDir/ #  relativeDir/ 第一个字符如果不是/表示相对路径最后以/结尾表示目录
    
    ADD test.txt /relativeDir/ #把context目录下的test.txt复制到镜像系统中绝对路径/relativeDir/m
    
4.12. **COPY
  1. 格式:

    COPY [--chown=<user>:<group>] <src>...<dest>
    COPY [--chown=<user>:<group>] ["<src>","<src>",...,"<dest>"]
    当后一个形式的路径可以有空格、转义字符以及环境变量。
    <src>:如果是文件或者目录时,<src>路径会理解为docker build时context的相对路径.
    <dest>:是被构建镜像的文件系统的路径.可以是绝对路径或者相对于<WORKDIR>的相对路径
    --chown:指明新创建的文件在镜像中的所有权默认是UID和GID为0即root用户
    <user>:<group>:可以是用户名、群组名或者UID、GID的组合
    
  2. 作用:

    COPY instruction从< src >中复制新文件、新目录至容器中< dest >位置.其余与ADD instruction类似

  3. 注意:

    1. –chown: 参数只能支持构建Linux容器的Dockerfile,不支持构建Window容器的Dockerfile,由于只有Linux系统下有/etc/passwd以及/etc/group两个记录着UserName与UID、GroupName与GID转换。

    2. < src >可能有通配符,匹配规则

    3. 在这里插入图片描述

      < src > 只能指向context内部,不能context之外

    4. 如果 < src >是文件夹

    1. 如果< src >是文件
      在这里插入图片描述

      重点:如果< src >是文件,< dest >后面没有反斜杠,则被认为对< src >文件的重命名

4.13.**ENTRYPOINT
  1. 格式:

    ENTRYPOINT ["executable","param1","param2"] (exec form)
    ENTRYPOINT command param1 param2   (shell form)
    首选exec form的ENTRYPOINT
    
  2. 作用:

    ENTRYPOINT可以配置将作为可执行文件运行的容器。

  3. exec form ENTRYPOINT 例子

    1. 作用:

      Command line arguments to docker run <image> will be appended after all elements in an exec form ENTRYPOINT, and will override all elements specified using CMD

      docker run < image >命令行中的参数将会添加到exec form ENTRYPOINT元素之后执行,且将会覆盖CMD指令.

4.14.** WORKDIR
  1. 格式:

    WORKDIR <path>
    
  2. 作用:

在这里插入图片描述

RUNCMDENTRYPOINTCOPYADD设置工作目录,换句话说上述5个Instruction的相对路径都是相对于设置的WORKDIR

相对路径的写法:不以“/”开头

绝对路径的写法:以“/”开头

如果不设置WORKDIR,默认为/即镜像中的root根路径,In practice, if you aren’t building a Dockerfile from scratch (FROM scratch), the WORKDIR may likely be set by the base image you’re using.,所以自己构建新镜像时最好要设置WORKDIR.

  1. 注意:

    1. WORKDIR instruction可以使用多次,最终的WORKDIR是多个WORKDIR instruction的叠加.

      WORKDIR /a #绝对路径/a
      WORKDIR b  #相对于前一个WORKDIR的相对路径即/a/b
      WORKDIR c  #相对于前一个WORKDIR的相对路径即/a/b/c
      RUN pwd
      上面的dockerfile的完整的WORKDIR为/a/b/c
      
    2. WORKDIR 指令可以 解析之前使用 ENV 设置的环境变量。 您只能使用在 Dockerfile 中显式设置的环境变量。

      ENV DIRPATH=/path
      WORKDIR $DIRPATH/$DIRNAME
      输出的结果:/path/$DIRNAME,由于$DIRNAME没有在dockerfile中显式设置
      
4.15.USER
  1. 格式:

5. .dockerignore 文件

  1. 位置:存放在docker build 的context的根目录(即当执行docker build 时会在context的根目录下寻找.dockerignore文件)

  2. 作用:If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it.This helps to avoid unnecessarily sending large or sensitive files and directories to the daemon and potentially adding them to images using ADD or COPY.

  3. 内容:

    1. .dockerigonre文件中的匹配的文件和文件夹,是以docker build的context为根目录

      即 /foo/bar则忽略context下foo子目录中的bar文件夹或者文件

    2. .dockerignore文件中第一行以#开头的认为是注释

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enQzEozk-1657461351131)(Dockerfile.assets/image-20220708201027546-16572822284984-16572823648315.png)]

    3. .dockerignore文件的匹配规则是按照 Go’s filepath.Match rules.以及表示context下的匹配任意层次的文件夹(包括context根目录)

      即**/* .go表示 will exclude all files that end with .go that are found in all directories, including the root of the build context.

    4. !开头表示可以排除例外情况

    5. .dockerignore甚至可以排除dockerfile文件以及.dockerignore文件

  4. 例子:

    # comment
    */temp*
    */*/temp*
    temp?
    *.md
    !README.md
    

在这里插入图片描述

*.md :排除context目录下所有以.md后缀的文件

!README.md:context目录下README.md文件不会被排除.

*.md
!README*.md
README-secret.md
排除的文件为:context下的*.md-!README*.md+README-secret.md

*.md
README-secret.md
!README*.md
排除的文件为:context下的*.md+README-secret.md-!README*.md=*.md-!README*.md

6.参考文献:

Dockerfile Reference

猜你喜欢

转载自blog.csdn.net/Blockchain210/article/details/125711734
今日推荐