当前位置:   article > 正文

[【docker常用命令系列】Dockerfile用法选项示例权威详解2_docker cmd

docker cmd

【docker常用命令系列】Dockerfile用法选项示例权威详解2

源自专栏《docker常用命令系列目录导航

CMD指令

CMD指令设置在从镜像运行容器时要执行的命令。

你可以使用shell形式或exec形式指定CMD指令:

  • CMD [“executable”,“param1”,“param2”](exec形式)
  • CMD [“param1”,“param2”](exec形式,作为ENTRYPOINT的默认参数)
  • CMD command param1 param2(shell形式)

一个Dockerfile中只能有一个CMD指令。如果列出多个CMD,只有最后一个会生效。

CMD的目的是为正在执行的容器提供默认值。这些默认值可以包括可执行文件,也可以省略可执行文件,在这种情况下,你必须指定ENTRYPOINT指令。

如果希望容器每次都运行相同的可执行文件,则应考虑使用ENTRYPOINT结合CMD。查看ENTRYPOINT。如果用户为docker run指定参数,它们将覆盖CMD中指定的默认值,但仍然使用默认的ENTRYPOINT。

如果CMD用于为ENTRYPOINT指令提供默认参数,那么CMD和ENTRYPOINT指令都应该以exec形式指定。

注意

不要将RUN与CMD混淆。RUN实际上运行一个命令并提交结果;CMD不会在构建时执行任何操作,而是为镜像指定预期的命令。

LABEL指令

LABEL = = = …

LABEL指令为镜像添加元数据。一个LABEL是一个键值对。如果在LABEL值中包含空格,可以使用引号和反斜杠,就像在命令行解析中一样。下面是一些用法示例:

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."
  • 1
  • 2
  • 3
  • 4
  • 5

一个镜像可以有多个标签。你可以在单行上指定多个标签。在Docker 1.10之前,这会减少最终镜像的大小,但现在不再如此。你仍然可以选择在单个指令中指定多个标签,有两种方式:

LABEL multi.label1="value1" multi.label2="value2" other="value3"

LABEL multi.label1="value1" \
      multi.label2="value2" \
      other="value3"
  • 1
  • 2
  • 3
  • 4
  • 5

注意

确保使用双引号而不是单引号。特别是在使用字符串插值时(例如LABEL example=“foo-$ENV_VAR”),单引号将保持字符串不变,而不解压变量的值。

包含在基本或父镜像中(在FROM行中的镜像)的标签将被继承到你的镜像。如果标签已经存在但具有不同的值,则最近应用的值将覆盖之前设置的任何值。

要查看镜像的标签,可以使用docker image inspect命令。你可以使用–format选项仅显示标签;

docker image inspect --format='{
   {json .Config.Labels}}' myimage
  • 1
  • 2

MAINTAINER(已弃用)

MAINTAINER

MAINTAINER指令设置生成镜像的Author字段。LABEL指令是这个的一个更灵活的版本,你应该使用它,因为它可以设置你需要的任何元数据,并且可以轻松查看,例如使用docker inspect。要设置与MAINTAINER字段对应的标签,你可以使用:

LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
  • 1

这样就可以在docker inspect中与其他标签一起查看。

EXPOSE指令

EXPOSE [/…]

EXPOSE指令通知Docker容器在运行时监听指定的网络端口。你可以指定端口是否监听TCP或UDP,默认情况下如果不指定协议则是TCP。

EXPOSE指令实际上不会发布端口。它起到了一个文档的作用,用于构建镜像的人员和运行容器的人员之间,指示意图发布哪些端口。要在运行容器时发布端口,请使用docker run时的-p标志来发布和映射一个或多个端口,或者使用-P标志来发布所有暴露的端口并将它们映射到高级端口。

默认情况下,EXPOSE假定TCP。你也可以指定UDP:

EXPOSE 80/udp
  • 1

要同时在TCP和UDP上暴露,包括两行:

EXPOSE 80/tcp
EXPOSE 80/udp
  • 1
  • 2

在这种情况下,如果你使用docker run时使用-P,端口将分别为TCP和UDP暴露一次。请记住,-P在主机上使用一个临时的高级端口,因此TCP和UDP不会使用相同的端口。

无论EXPOSE设置如何,你都可以在运行时使用-p标志来覆盖它们。例如:

docker run -p 80:80/tcp -p 80:80/udp ...
  • 1

要在主机系统上设置端口重定向,请查看使用-P标志。docker network命令支持为容器之间的通信创建网络,无需暴露或发布特定端口,因为连接到网络的容器可以通过任何端口相互通信。有关详细信息,请参阅此功能的概述。

ADD指令

ADD有两种形式。后一种形式是用于包含空格路径的必需形式。

ADD [OPTIONS] <src> ... <dest>
ADD [OPTIONS] ["<src>", ... "<dest>"]
  • 1
  • 2

可用的[OPTIONS]有:

  • –keep-git-dir
  • –checksum
  • –chown
  • –chmod
  • –link
  • –exclude

ADD指令将从复制新文件、目录或远程文件URL,并将它们添加到镜像的文件系统中的路径中。

可以指定多个资源,但如果它们是文件或目录,它们的路径将被解释为相对于构建上下文源的路径。

每个可能包含通配符,并将使用Go的filepath.Match规则进行匹配。例如:

要添加以“hom”开头的构建上下文根目录中的所有文件:

ADD hom* /mydir/
  • 1

在以下示例中,?是一个单字符通配符,例如匹配“home.txt”。

ADD hom?.txt /mydir/
  • 1

是一个绝对路径,或者相对于WORKDIR的路径,源将被复制到目标容器内部。

下面的示例使用相对路径,将“test.txt”添加到/relativeDir/中:

ADD test.txt relativeDir/
  • 1

而这个示例使用绝对路径,将“test.txt”添加到/absoluteDir/中:

ADD test.txt /absoluteDir/
  • 1

当添加包含特殊字符(如[和])的文件或目录时,需要遵循Golang规则对这些路径进行转义,以防止它们被视为匹配模式。例如,要添加一个名为arr[0].txt的文件,请使用以下方式;

ADD arr[[]0].txt /mydir/
  • 1

在是远程文件URL的情况下,目标文件的权限将为600。如果被检索的远程文件具有HTTP Last-Modified标头,则将使用该标头的时间戳来设置目标文件的修改时间。但是,就像处理ADD期间的任何其他文件一样,修改时间不包括在确定文件是否已更改以及是否应更新缓存中。

注意:

如果通过STDIN传递Dockerfile进行构建(docker build - < somefile),则没有构建上下文,因此Dockerfile只能包含基于URL的ADD指令。你也可以通过STDIN传递一个压缩的归档文件:(docker build - < archive.tar.gz),归档的根目录中的Dockerfile和归档的其余部分将用作构建的上下文。

如果你的URL文件受到身份验证保护,需要在容器内部使用RUN wget、RUN curl或另一个工具,因为ADD指令不支持身份验证。

注意:

如果构建过程中第一次遇到ADD指令,如果的内容已更改,将使Dockerfile中所有后续指令的缓存失效。这包括使RUN指令的缓存失效。查看Dockerfile最佳实践指南-利用构建缓存以获取更多信息。

ADD遵循以下规则:

  • 路径必须在构建上下文中;你不能使用ADD …/something /something,因为构建器只能访问构建上下文中的文件,而…/something指定构建上下文根目录的父文件或目录。
  • 如果是一个URL且不以斜杠结尾,则文件名将从URL中推断出,并将文件下载到/。例如,ADD http://example.com/foobar /将创建文件/foobar。URL必须具有一个非平凡的路径,以便在这种情况下可以发现适当的文件名(例如http://example.com不起作用)。
  • 如果是目录,则整个目录的内容都将被复制,包括文件系统元数据。

注意:

  • 目录本身不会被复制,只有其内容。

  • 如果是识别的压缩格式(identity、gzip、bzip2或xz)的本地tar存档,则它将作为目录进行解压。从远程URL获取的资源不会解压缩。当复制或解压目录时,它的行为类似于tar -x。结果是:

    • 存在于目标路径的任何内容
    • 源树的内容,解决冲突有利于“2.”,逐个文件解决。

注意:

  • 是否将文件标识为识别的压缩格式是仅基于文件内容而不是文件名来完成的。例如,如果一个空文件碰巧以.tar.gz结尾,这不会被识别为一个压缩文件,并且不会生成任何解压缩错误消息,而是简单地将文件复制到目标位置。
  • 如果是其他类型的文件,它将单独复制,并且连同其元数据一起复制。在这种情况下,如果以斜杠/结尾,则将被视为目录,并且的内容将被写入到/base()中。
  • 如果指定了多个资源,无论是直接指定还是由于使用通配符,必须是目录,并且必须以斜杠/结尾。
  • 如果是一个文件,并且没有以斜杠结尾,则的内容将被写为文件名。
  • 如果不存在,它将被创建,并且在其路径中将创建所有缺失的目录。

添加私有Git仓库

要通过SSH添加私有仓库,请创建以下形式的Dockerfile:

# syntax=docker/dockerfile:1
FROM alpine
ADD git@git.example.com:foo/bar.git /bar
  • 1
  • 2
  • 3

可以使用docker build --ssh或buildctl build --ssh构建此Dockerfile,例如:

docker build --ssh default

buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --ssh default
  • 1
  • 2
  • 3

ADD --keep-git-dir

ADD [--keep-git-dir=<boolean>] <src> ... <dir>
  • 1

当是远程Git仓库的HTTP或SSH地址时,BuildKit默认会将Git仓库的内容添加到镜像中,不包括.git目录

–keep-git-dir=true标志允许保留.git目录。

# syntax=docker/dockerfile:1
FROM alpine
ADD --keep-git-dir=true https://github.com/moby/buildkit.git#v0.10.1 /buildkit
  • 1
  • 2
  • 3

ADD --checksum

ADD [--checksum=<hash>] <src> ... <dir>
  • 1

–checksum标志允许验证远程资源的校验和:

ADD --checksum=sha256:24454f830cdb571e2c4ad15481119c43b3cafd48dd869a9b2945d1036d1dc68d https://mirrors.edge.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz /
  • 1

–checksum标志目前仅支持HTTP来源。

ADD --chown --chmod

参见COPY --chown --chmod。

ADD --link

参见COPY --link。

ADD --exclude

参见COPY --exclude。

COPY指令

COPY有两种形式。后一种形式是用于包含空格路径的必需形式。

COPY [OPTIONS] <src> ... <dest>
COPY [OPTIONS] ["<src>", ... "<dest>"]
  • 1
  • 2

可用的[OPTIONS]有:

  • –chown
  • –chmod
  • –link
  • –parents
  • –exclude

COPY指令将从复制新文件或目录,并将它们添加到容器的文件系统中的路径中

可以指定多个资源,但文件和目录的路径将被解释为相对于构建上下文源的路径。

每个可能包含通配符,并将使用Go的filepath.Match规则进行匹配。例如:

要添加以“hom”开头的构建上下文根目录中的所有文件:

COPY hom* /mydir/
  • 1

在以下示例中,?是一个单字符通配符,例如匹配“home.txt”。

COPY hom?.txt /mydir/
  • 1

是一个绝对路径,或者相对于WORKDIR的路径,源将被复制到目标容器内部。

下面的示例使用相对路径,将“test.txt”添加到/relativeDir/中:

COPY test.txt relativeDir/
  • 1

而这个示例使用绝对路径,将“test.txt”添加到/absoluteDir/中:

COPY test.txt /absoluteDir/
  • 1

当复制包含特殊字符(如[和])的文件或目录时,需要遵循Golang规则对这些路径进行转义,以防止它们被视为匹配模式。例如,要复制名为arr[0].txt的文件,请使用以下方式:

COPY arr[[]0].txt /mydir/
  • 1

注意:

如果通过STDIN构建(docker build - < somefile),则没有构建上下文,因此无法使用COPY。

可选地,COPY接受一个–from=标志,可以用于将源位置设置为先前的构建阶段(使用FROM … AS 创建)的名称,而不是用户发送的构建上下文。如果找不到具有指定名称的构建阶段,则尝试使用具有相同名称的镜像。

COPY遵循以下规则:

  • 路径必须在构建上下文中;你不能使用COPY …/something /something,因为构建器只能访问构建上下文中的文件,而…/som
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/834640
推荐阅读
相关标签
  

闽ICP备14008679号