Dockerfile指令详解
FROM
FROM [--platform=<platform>] <image> [AS <name>]
要么
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
要么
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
该FROM
指令初始化一个新的构建阶段,并为后续指令设置 基本映像。因此,有效的Dockerfile
必须从FROM
指令开始。该图像可以是任何有效的图像- 从公共存储库中拉出图像特别容易启动。
-
ARG
是先于仅指示FROM
在Dockerfile
。请参阅了解ARG和FROM之间的相互作用。 -
FROM
可以一次出现多次Dockerfile
以创建多个映像,也可以将一个构建阶段作为对另一个构建阶段的依赖。只需在每个新FROM
指令之前记录一次提交输出的最后一个图像ID 。每个FROM
指令清除由先前指令创建的任何状态。 - 可选的名称可以通过添加给予一个新的构建阶段
AS name
的FROM
指令。该名称可以在后续版本FROM
和COPY --from=
说明中使用,以引用此阶段中构建的映像。 - 该
tag
或digest
值是可选的。如果您忽略其中任何一个latest
,那么缺省情况下构建器将采用标签。如果构建器找不到该tag
值,则返回错误。
--platform
在FROM
引用多平台图像的情况下,可选标志可用于指定图像的平台。例如,linux/amd64
, linux/arm64
,或windows/amd64
。默认情况下,使用构建请求的目标平台。可以在此标志的值中使用全局构建参数,例如,自动平台ARG 允许您将阶段强制到本机构建平台(--platform=$BUILDPLATFORM
),并使用它来交叉编译到阶段内部的目标平台。
了解ARG和FROM之间的交互方式
FROM
指令支持由ARG
第一指令之前的任何指令声明的变量FROM
。
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extras
ARG
在a之前的声明FROM
位于构建阶段之外,因此不能在a之后的任何指令中使用它FROM
。要ARG
在第一次FROM
使用声明之前使用默认值,请在ARG
构建阶段使用不带值的指令:
ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version
RUN
RUN有2种形式:
-
RUN
(shell形式,命令在shell中运行,默认情况下/bin/sh -c
在Linux或cmd /S /C
Windows 上运行) -
RUN ["executable", "param1", "param2"]
(执行表格)
该RUN
指令将在当前图像顶部的新层中执行所有命令,并提交结果。生成的提交图像将用于中的下一步Dockerfile
。
分层RUN
指令和生成提交符合Docker的核心概念,在Docker上,提交很便宜,并且可以从映像历史记录的任何位置创建容器,就像源代码控制一样。
在EXEC形式使得能够避免壳串改写(munging),并RUN
使用不包含指定壳可执行基本图像的命令。
可以使用以下 命令更改shell形式的默认shell SHELL
。
在shell形式中,可以使用\
(反斜杠)将一条RUN指令继续到下一行。例如,考虑以下两行:
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
它们在一起等效于以下这一行:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
注意:要使用'/ bin / sh'以外的其他shell,请使用exec形式传入所需的shell。例如,
RUN ["/bin/bash", "-c", "echo hello"]
注意:exec表单被解析为JSON数组,这意味着您必须在单词而非单引号(')周围使用双引号(“)。
注意:与shell表单不同,exec表单不会调用命令shell。这意味着不会进行常规的外壳处理。例如,
RUN [ "echo", "$HOME" ]
将不会对进行变量替换$HOME
。如果要进行shell处理,则可以使用shell形式或直接执行shell,例如:RUN [ "sh", "-c", "echo $HOME" ]
。当使用exec表单并直接执行shell时(例如在shell表单中),是由shell进行环境变量扩展,而不是docker。注意:在JSON格式中,必须转义反斜杠。这在Windows中特别有用,在Windows中反斜杠是路径分隔符。否则,由于无效的JSON,以下行将被视为shell形式,并且会以意外的方式失败:
RUN ["c:\windows\system32\tasklist.exe"]
此示例的正确语法为:RUN ["c:\\windows\\system32\\tasklist.exe"]
RUN
下一次构建期间,指令缓存不会自动失效。类似指令的缓存 RUN apt-get dist-upgrade -y
将在下一个构建中重用。RUN
指令的缓存可以通过使用--no-cache
标志来使无效,例如docker build --no-cache
。
有关更多信息,请参见Dockerfile
最佳实践指南。
RUN
指令的高速缓存可以被ADD
指令无效。有关详情,请参见 下文。
已知问题
-
问题783是有关使用AUFS文件系统时可能发生的文件权限问题。例如,您在尝试
rm
文件过程中可能会注意到它。对于具有最新aufs版本的系统(即,
dirperm1
可以设置安装选项),docker将尝试通过使用options挂载层来尝试自动修复问题dirperm1
。有关dirperm1
选项的更多详细信息,请参见aufs
手册页如果您的系统不支持
dirperm1
,则该问题描述了一种解决方法。
CMD
该CMD
指令具有三种形式:
-
CMD ["executable","param1","param2"]
(exec形式,这是首选形式) -
CMD ["param1","param2"]
(作为ENTRYPOINT的默认参数) -
CMD command param1 param2
(外壳形式)
CMD
指令中只能有一条指令Dockerfile
。如果您列出多个,CMD
则只有最后一个CMD
才会生效。
a的主要目的CMD
是为执行中的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一条ENTRYPOINT
指令。
注意:如果
CMD
用于提供ENTRYPOINT
指令的默认参数,则CMD
和ENTRYPOINT
指令均应使用JSON数组格式指定。
注意:exec表单被解析为JSON数组,这意味着您必须在单词而非单引号(')周围使用双引号(“)。
注意:与shell表单不同,exec表单不会调用命令shell。这意味着不会进行常规的外壳处理。例如,
CMD [ "echo", "$HOME" ]
将不会对进行变量替换$HOME
。如果要进行shell处理,则可以使用shell形式或直接执行shell,例如:CMD [ "sh", "-c", "echo $HOME" ]
。当使用exec表单并直接执行shell时(例如在shell表单中),是由shell进行环境变量扩展,而不是docker。
当以shell或exec格式使用时,该CMD
指令设置运行映像时要执行的命令。
如果您使用的shell形式CMD
,则将在中``执行 /bin/sh -c
:
FROM ubuntu
CMD echo "This is a test." | wc -
如果要在 `` 没有外壳****的****情况下****运行,则必须将命令表示为JSON数组,并提供可执行文件的完整路径。 此数组形式是的首选格式CMD
。任何其他参数必须在数组中分别表示为字符串:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
如果您希望容器每次都运行相同的可执行文件,则应考虑ENTRYPOINT
与结合使用CMD
。请参阅 ENTRYPOINT。
如果用户指定的参数,docker run
则它们将覆盖中指定的默认值CMD
。
注意:请勿
RUN
与混淆CMD
。RUN
实际上运行命令并提交结果;CMD
在生成时不执行任何操作,但指定映像的预期命令。
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
该LABEL
指令将元数据添加到图像。A 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."
一幅图像可以有多个标签。您可以在一行上指定多个标签。在Docker 1.10之前的版本中,这减小了最终映像的大小,但是情况不再如此。您仍然可以通过以下两种方式之一选择在一条指令中指定多个标签:
LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
基本或父图像(行中的图像FROM
)中包含的标签由您的图像继承。如果标签已经存在但具有不同的值,则最近应用的值将覆盖任何先前设置的值。
要查看图像的标签,请使用docker inspect
命令。
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
EXPOSE
EXPOSE <port> [<port>/<protocol>...]
该EXPOSE
指令通知Docker容器在运行时监听指定的网络端口。您可以指定端口是侦听TCP还是UDP,如果未指定协议,则默认值为TCP。
该EXPOSE
指令实际上并未发布端口。它充当构建映像的人与运行容器的人之间的一种文档类型,有关打算发布哪些端口的信息。要在运行容器时实际发布端口,请使用-p
标记on docker run
发布和映射一个或多个端口,或者使用-P
标记发布所有公开的端口并将它们映射到高阶端口。
默认情况下,EXPOSE
假定为TCP。您还可以指定UDP:
EXPOSE 80/udp
要同时在TCP和UDP上公开,请包括以下两行:
EXPOSE 80/tcp
EXPOSE 80/udp
在这种情况下,如果-P
与一起使用docker run
,则该端口仅对TCP公开一次,对于UDP公开一次。请记住,-P
该端口在主机上使用临时的高阶主机端口,因此该端口对于TCP和UDP将是不同的。
无论EXPOSE
设置如何,都可以在运行时使用该-p
标志覆盖它们。例如
docker run -p 80:80/tcp -p 80:80/udp ...
要在主机系统上设置端口重定向,请参阅使用-P标志。该docker network
命令支持创建网络以在容器之间进行通信,而无需暴露或发布特定端口,因为连接到网络的容器可以通过任何端口相互通信。有关详细信息,请参阅 此功能概述。
ENV
ENV <key> <value>
ENV <key>=<value> ...
该ENV
指令将环境变量设置为value
。此值将在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
该ENV
指令有两种形式。第一种形式,ENV
会将一个变量设置为一个值。第一个空格之后的整个字符串将被视为``-包括空格字符。该值将为其他环境变量解释,因此如果不对引号字符进行转义,则将其删除。
第二种形式ENV = ...
允许一次设置多个变量。请注意,第二种形式在语法中使用等号(=),而第一种形式则不使用等号(=)。像命令行解析一样,引号和反斜杠可用于在值中包含空格。
例如:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
和
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
将在最终图像中产生相同的净结果。
ENV
从结果映像运行容器时,使用设置的环境变量将保留。您可以使用查看值docker inspect
,并使用更改它们docker run --env =
。
注意:环境持久性可能导致意外的副作用。例如,设置
ENV DEBIAN_FRONTEND noninteractive
可能会使基于Debian的映像上的apt-get用户感到困惑。要为单个命令设置值,请使用RUN =
。
ADD
ADD有两种形式:
ADD [--chown=:] ...
-
ADD [--chown=:] ["",... ""]
(此格式对于包含空格的路径是必需的)
注意:此
--chown
功能仅在用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。由于用户和组所有权概念不会在Linux和Windows之间转换,因此使用/etc/passwd
和/etc/group
将用户名和组名转换为ID的使用限制了此功能仅对基于Linux OS的容器可用。
该ADD
指令从中复制新文件,目录或远程文件URL ,并将它们添加到路径中映像的文件系统中
。
``可以指定多个资源,但是如果它们是文件或目录,则将其路径解释为相对于构建上下文源的路径。
每个都``可能包含通配符,并且匹配将使用Go的 filepath.Match规则完成。例如:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
的``是一个绝对路径,或相对于一个路径WORKDIR
,到其中的源将在目标容器内进行复制。
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # adds "test" to /absoluteDir/
添加包含特殊字符(例如[
和]
)的文件或目录时,您需要按照Golang规则转义这些路径,以防止将它们视为匹配模式。例如,要添加名为的文件arr[0].txt
,请使用以下命令;
ADD arr[[]0].txt /mydir/ # copy a file named "arr[0].txt" to /mydir/
除非可选--chown
标志指定给定的用户名,组名或UID / GID组合以请求对所添加内容的特定所有权,否则所有新文件和目录的UID和GID均为0 。--chown
标志的格式允许使用用户名和组名字符串,或直接整数UID和GID的任意组合。提供不带组名的用户名或不带GID的UID将使用与GID相同的数字UID。如果提供了用户名或组名,则将使用容器的根文件系统 /etc/passwd
和/etc/group
文件来分别执行从名称到整数UID或GID的转换。以下示例显示了该--chown
标志的有效定义:
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
如果容器根文件系统不包含/etc/passwd
或 /etc/group
文件,并且在--chown
标志中使用了用户名或组名,则该构建将在该ADD
操作上失败。使用数字ID不需要查找,并且不依赖于容器根文件系统内容。
如果``是远程文件URL,则目标将具有600的权限。如果正在检索的远程文件具有HTTP Last-Modified
标头,则该标头中的时间戳将用于设置mtime
目标文件上的时间戳。但是,就像在期间处理的任何其他文件一样ADD
,mtime
该文件是否已更改以及是否应更新缓存的确定将不包括在内。
注意:如果通过传递
Dockerfile
STDIN(docker build - < somefile
)进行构建,则没有构建上下文,因此Dockerfile
只能包含基于URL的ADD
指令。您还可以通过STDIN:(docker build - < archive.tar.gz
)传递压缩的归档文件,归档文件Dockerfile
根目录中的,归档文件的其余部分将用作构建的上下文。
注意:如果您的URL文件受身份验证保护,则您将需要使用
RUN wget
,RUN curl
或从容器中使用其他工具,因为该ADD
指令不支持身份验证。
注意:
ADD
如果Dockerfile中的内容``已更改,则第一个遇到的指令将使Dockerfile中所有后续指令的缓存无效。这包括使高速缓存中的RUN
指令无效。有关更多信息,请参见Dockerfile
最佳实践指南。
ADD
遵守以下规则:
- 该``路径必须是内部语境的构建; 您不能这样做
ADD ../something /something
,因为a的第一步docker build
是将上下文目录(和子目录)发送到docker守护程序。 - 如果
是URL,
并且不以斜杠结尾,则从URL下载文件并将其复制到``。 - 如果
是URL并
以斜杠结尾,则从URL推断文件名,然后将文件下载到/
。例如,ADD http://example.com/foobar /
将创建文件/foobar
。该URL必须具有非平凡的路径,以便在这种情况下可以发现适当的文件名(http://example.com
将不起作用)。 - 如果``是目录,则将复制目录的整个内容,包括文件系统元数据。
注意:目录本身不会被复制,只是其内容被复制。
-
如果``是以公认的压缩格式(身份,gzip,bzip2或xz)的本地 tar归档文件,则将其解压缩为目录。来自远程 URL的资源不会被解压缩。复制或解压缩目录时,其行为与相同
tar -x
,结果是以下各项的并集:- 目标路径上存在的任何内容和
- 源代码树的内容,已解决冲突,而选择了“ 2”。在逐个文件的基础上。
注意:文件是否被识别为公认的压缩格式仅根据文件的内容而不是文件的名称来完成。例如,如果一个空文件恰好以
.tar.gz
该文件结尾,则不会被识别为压缩文件,并且不会生成任何类型的解压缩错误消息,而是会将文件简单地复制到目标位置。 -
如果
是任何其他类型的文件,它将与元数据一起单独复制。在这种情况下,如果
以斜杠结尾/
,则将其视为目录,并将其内容``写入/base()
。 -
如果
直接或由于使用通配符而指定了多个资源,则该资源
必须是目录,并且必须以斜杠结尾/
。 -
如果
不以斜杠结尾,则将其视为常规文件,并将其内容
写入``。 -
如果``不存在,它将与路径中所有缺少的目录一起创建。
COPY
COPY有两种形式:
COPY [--chown=:] ...
-
COPY [--chown=:] ["",... ""]
(此格式对于包含空格的路径是必需的)
注意:此
--chown
功能仅在用于构建Linux容器的Dockerfiles上受支持,而在Windows容器上不起作用。由于用户和组所有权概念不会在Linux和Windows之间转换,因此使用/etc/passwd
和/etc/group
将用户名和组名转换为ID的使用限制了此功能仅对基于Linux OS的容器可用。
该COPY
指令从中复制新文件或目录,并将它们添加到路径中容器的文件系统中
。
``可以指定多个资源,但是文件和目录的路径将被解释为相对于构建上下文的源。
每个都``可能包含通配符,并且匹配将使用Go的 filepath.Match规则完成。例如:
COPY hom* /mydir/ # adds all files starting with "hom"
COPY hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
的``是一个绝对路径,或相对于一个路径WORKDIR
,到其中的源将在目标容器内进行复制。
COPY test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/ # adds "test" to /absoluteDir/
复制包含特殊字符(例如[
和]
)的文件或目录时,您需要按照Golang规则对这些路径进行转义,以防止将它们视为匹配模式。例如,要复制名为的文件arr[0].txt
,请使用以下命令;
COPY arr[[]0].txt /mydir/ # copy a file named "arr[0].txt" to /mydir/
除非可选--chown
标志指定给定的用户名,组名或UID / GID组合以请求对复制内容的特定所有权,否则所有新文件和目录的UID和GID均为0 。--chown
标志的格式允许使用用户名和组名字符串,或直接整数UID和GID的任意组合。提供不带组名的用户名或不带GID的UID将使用与GID相同的数字UID。如果提供了用户名或组名,则将使用容器的根文件系统 /etc/passwd
和/etc/group
文件来分别执行从名称到整数UID或GID的转换。以下示例显示了该--chown
标志的有效定义:
COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/
如果容器根文件系统不包含/etc/passwd
或 /etc/group
文件,并且在--chown
标志中使用了用户名或组名,则该构建将在该COPY
操作上失败。使用数字ID不需要查找,并且不依赖于容器根文件系统内容。
注意:如果使用STDIN(
docker build - < somefile
)进行构建,则没有构建上下文,因此COPY
无法使用。
(可选)COPY
接受一个标志--from=
,该标志可用于将源位置设置为将使用的先前构建阶段(使用创建FROM .. AS
),而不是用户发送的构建上下文。该标志还接受为以FROM
指令开头的所有先前构建阶段分配的数字索引 。如果找不到具有指定名称的构建阶段,则尝试使用具有相同名称的映像代替。
COPY
遵守以下规则:
- 该``路径必须是内部语境的构建; 您不能这样做
COPY ../something /something
,因为a的第一步docker build
是将上下文目录(和子目录)发送到docker守护程序。 - 如果``是目录,则将复制目录的整个内容,包括文件系统元数据。
注意:目录本身不会被复制,只是其内容被复制。
- 如果
是任何其他类型的文件,它将与元数据一起单独复制。在这种情况下,如果
以斜杠结尾/
,则将其视为目录,并将其内容``写入/base()
。 - 如果
直接或由于使用通配符而指定了多个资源,则该资源
必须是目录,并且必须以斜杠结尾/
。 - 如果
不以斜杠结尾,则将其视为常规文件,并将其内容
写入``。 - 如果``不存在,它将与路径中所有缺少的目录一起创建。
ENTRYPOINT
ENTRYPOINT有两种形式:
-
ENTRYPOINT ["executable", "param1", "param2"]
(执行表格,首选) -
ENTRYPOINT command param1 param2
(外壳形式)
An ENTRYPOINT
允许您配置将作为可执行文件运行的容器。
例如,以下将使用其默认内容启动nginx,并监听端口80:
docker run -i -t --rm -p 80:80 nginx
命令行参数to docker run
将以exec形式附加在所有元素之后ENTRYPOINT
,并将覆盖使用指定的所有元素CMD
。这允许将参数传递给入口点,即,docker run -d
将-d
参数传递给入口点。您可以ENTRYPOINT
使用该docker run --entrypoint
标志覆盖该指令。
所述壳形式防止任何CMD
或run
被使用命令行参数,但具有的缺点是你ENTRYPOINT
将开始作为的子命令/bin/sh -c
,其不通过信号。这意味着可执行文件将不是容器的PID 1
-并且将不会接收Unix信号-因此您的可执行文件将不会SIGTERM
从接收 到docker stop
。
只有中的最后一条ENTRYPOINT
指令Dockerfile
才会生效。
执行表格ENTRYPOINT示例
您可以使用exec形式的ENTRYPOINT
设置相当稳定的默认命令和参数,然后使用这两种形式的CMD
设置更可能被更改的其他默认值。
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
运行容器时,可以看到这top
是唯一的过程:
$ docker run -it --rm --name test top -H
top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05
Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2056668 total, 1616832 used, 439836 free, 99352 buffers
KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 19744 2336 2080 R 0.0 0.1 0:00.04 top
要进一步检查结果,可以使用docker exec
:
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 2.6 0.1 19752 2352 ? Ss+ 08:24 0:00 top -b -H
root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps aux
您也可以使用优雅地请求top
关闭docker stop test
。
下面Dockerfile
显示了使用ENTRYPOINT
来在前台运行Apache(即,作为PID 1
):
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
如果需要为单个可执行文件编写启动脚本,则可以使用exec
和gosu
命令确保最终的可执行文件接收Unix信号:
#!/usr/bin/env bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
最后,如果您需要在关机时进行一些额外的清理(或与其他容器通信),或者要协调多个可执行文件,则可能需要确保ENTRYPOINT
脚本接收Unix信号,将其传递,然后执行一些更多的工作:
#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too
# USE the trap if you need to also do manual cleanup after the service is stopped,
# or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM
# start service in background here
/usr/sbin/apachectl start
echo "[hit enter key to exit] or run 'docker stop <container>'"
read
# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop
echo "exited $0"
如果使用来运行该映像docker run -it --rm -p 80:80 --name test apache
,则可以使用docker exec
或来检查容器的进程docker top
,然后要求脚本停止Apache:
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2
root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start
www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux
$ docker top test
PID USER COMMAND
10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054 root /usr/sbin/apache2 -k start
10055 33 /usr/sbin/apache2 -k start
10056 33 /usr/sbin/apache2 -k start
$ /usr/bin/time docker stop test
test
real 0m 0.27s
user 0m 0.03s
sys 0m 0.03s
注意:您可以
ENTRYPOINT
使用来覆盖设置--entrypoint
,但这只能将二进制文件设置为exec(sh -c
将不使用)。
注意:exec表单被解析为JSON数组,这意味着您必须在单词而非单引号(')周围使用双引号(“)。
注意:与shell表单不同,exec表单不会调用命令shell。这意味着不会进行常规的外壳处理。例如,
ENTRYPOINT [ "echo", "$HOME" ]
将不会对进行变量替换$HOME
。如果要进行shell处理,则可以使用shell形式或直接执行shell,例如:ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
。当使用exec表单并直接执行shell时(例如在shell表单中),是由shell进行环境变量扩展,而不是docker。
Shell form ENTRYPOINT example
您可以为指定一个纯字符串ENTRYPOINT
,它将在中执行/bin/sh -c
。这种形式将使用外壳处理来替代外壳环境变量,并且将忽略任何CMD
或docker run
命令行参数。为了确保能够正确docker stop
发出任何长期运行的ENTRYPOINT
可执行文件信号,您需要记住以以下命令启动它exec
:
FROM ubuntu
ENTRYPOINT exec top -b
运行此图像时,您将看到单个PID 1
过程:
$ docker run -it --rm --name test top
Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirq
Load average: 0.08 0.03 0.05 2/98 6
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root R 3164 0% 0% top -b
它将干净地退出docker stop
:
$ /usr/bin/time docker stop test
test
real 0m 0.20s
user 0m 0.02s
sys 0m 0.04s
如果您忘记添加exec
到您的开头ENTRYPOINT
:
FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1
然后,您可以运行它(为下一步命名):
$ docker run -it --name test top --ignored-param2
Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached
CPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirq
Load average: 0.01 0.02 0.05 2/101 7
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2
7 1 root R 3164 0% 0% top -b
您可以从输出中top
看到,指定ENTRYPOINT
的不是PID 1
。
如果随后运行docker stop test
,容器将无法干净退出- 超时后将stop
强制命令发送a SIGKILL
:
$ docker exec -it test ps aux
PID USER COMMAND
1 root /bin/sh -c top -b cmd cmd2
7 root top -b
8 root ps aux
$ /usr/bin/time docker stop test
test
real 0m 10.19s
user 0m 0.04s
sys 0m 0.03s
了解CMD和ENTRYPOINT如何相互作用
无论CMD
和ENTRYPOINT
指令定义运行的容器中时什么命令得到执行。很少有规则描述他们的合作。
- Dockerfile应该指定
CMD
或ENTRYPOINT
命令中的至少一个。 -
ENTRYPOINT
使用容器作为可执行文件时应定义。 -
CMD
应该用作ENTRYPOINT
在容器中定义命令或执行临时命令的默认参数的方式。 -
CMD
当使用其他参数运行容器时,将被覆盖。
下表显示了针对不同ENTRYPOINT
/ CMD
组合执行的命令:
没有入口点 | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“ exec_entry”,“ p1_entry”] | |
---|---|---|---|
没有CMD | 错误,不允许 | / bin / sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“ exec_cmd”,“ p1_cmd”] | exec_cmd p1_cmd | / bin / sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“ p1_cmd”,“ p2_cmd”] | p1_cmd p2_cmd | / bin / sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | / bin / sh -c exec_cmd p1_cmd | / bin / sh -c exec_entry p1_entry | exec_entry p1_entry / bin / sh -c exec_cmd p1_cmd |
注意:如果
CMD
是从基础图像定义的,则设置ENTRYPOINT
将重置CMD
为空值。在这种情况下,CMD
必须在当前图像中定义一个值。
VOLUME
VOLUME ["/data"]
该VOLUME
指令创建具有指定名称的安装点,并将其标记为保存来自本地主机或其他容器的外部安装的卷。该值可以是JSON数组,也可以是VOLUME ["/var/log/"]
具有多个参数的纯字符串,例如VOLUME /var/log
或VOLUME /var/log /var/db
。有关通过Docker客户端的更多信息/示例和安装说明,请参阅 通过Volumes共享目录 。
该docker run
命令使用基础映像内指定位置上存在的任何数据初始化新创建的卷。例如,考虑以下Dockerfile片段:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
该Dockerfile生成一个映像,该映像导致docker run
在处创建一个新的挂载点/myvol
并将该greeting
文件复制 到新创建的卷中。
有关指定卷的注意事项
关于。中的卷,请注意以下几点Dockerfile
。
-
基于Windows的容器上的卷:使用基于Windows的容器时,容器内的卷的目的地必须是以下之一:
- 不存在或空目录
- 除以下以外的驱动器
C:
- 从Dockerfile内更改卷:如果在声明了卷后有任何构建步骤更改了卷内的数据,则这些更改将被丢弃。
-
JSON格式:列表被解析为JSON数组。您必须用双引号(
"
)而不是单引号('
)括住单词。 -
主机目录是在容器运行时声明的:主机目录(挂载点)从本质上说是依赖于主机的。这是为了保留图像的可移植性,因为不能保证给定的主机目录在所有主机上都可用。因此,您无法从Dockerfile内挂载主机目录。该
VOLUME
指令不支持指定host-dir
参数。创建或运行容器时,必须指定安装点。
USER
USER <user>[:<group>] or
USER <UID>[:<GID>]
该USER
指令设置运行映像时以及用于任何映像时使用的用户名(或UID)和可选的用户组(或GID)RUN
,CMD
以及在 ENTRYPOINT
后面跟随的指令Dockerfile
。
警告:当用户没有主要组时,该映像(或以下说明)将与该
root
组一起运行。
在Windows上,如果不是内置帐户,则必须首先创建用户。这可以通过
net user
作为Dockerfile的一部分调用的命令来完成。
FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick
WORKDIR
WORKDIR /path/to/workdir
该WORKDIR
指令集的工作目录对任何RUN
,CMD
, ENTRYPOINT
,COPY
和ADD
它后面的说明Dockerfile
。如果WORKDIR
不存在,即使以后的任何Dockerfile
指令中都没有使用它,也将创建它。
该WORKDIR
指令可以在中多次使用Dockerfile
。如果提供了相对路径,则它将相对于上一条WORKDIR
指令的路径 。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
最终的输出pwd
命令这Dockerfile
将是 /a/b/c
。
该WORKDIR
指令可以解析先前使用设置的环境变量 ENV
。您只能使用在中显式设置的环境变量Dockerfile
。例如:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
最终pwd
命令的输出Dockerfile
将是 /path/$DIRNAME
ARG
ARG <name>[=<default value>]
该ARG
指令定义了一个变量,用户可以在构建时docker build
使用带有--build-arg =
标志的命令将变量传递给构建器。如果用户指定了未在Dockerfile中定义的构建参数,则构建会输出警告。
[Warning] One or more build-args [foo] were not consumed.
Dockerfile可能包含一个或多个ARG
指令。例如,以下是有效的Dockerfile:
FROM busybox
ARG user1
ARG buildno
...
警告:不建议使用构建时变量来传递诸如github密钥,用户凭据等机密。构建时变量值对于使用该
docker history
命令的图像的任何用户都是可见的。
默认值
的ARG
指令可以可选地包括一个默认值:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
如果ARG
指令具有缺省值,并且在构建时未传递任何值,那么构建器将使用缺省值。
范围
一个ARG
变量定义进入从在其上在限定的线效果Dockerfile
不从参数对命令行或其他地方使用。例如,考虑以下Dockerfile:
1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...
用户通过调用以下命令来构建此文件:
$ docker build --build-arg user=what_user .
USER
在第2行,at some_user
在user
变量3上定义为。USER
在第4 行,at 定义为what_user
as user
,并且what_user
在命令行上传递了值。在通过ARG
指令定义变量之前 ,对变量的任何使用都会导致一个空字符串。
的ARG
指令在它被定义的构建阶段结束推移的范围进行。要在多个阶段使用arg,每个阶段都必须包含ARG
指令。
FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS
FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS
使用ARG变量
您可以使用ARG
或ENV
指令指定该RUN
指令可用的变量。使用ENV
指令定义的环境变量 始终会覆盖ARG
同名指令。考虑使用带ENV
和ARG
指令的Dockerfile 。
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER v1.0.0
4 RUN echo $CONT_IMG_VER
然后,假定此映像是使用以下命令构建的:
$ docker build --build-arg CONT_IMG_VER=v2.0.1 .
在这种情况下,该RUN
指令将使用v1.0.0
而不是ARG
用户传递的设置:v2.0.1
此行为类似于Shell脚本,其中局部作用域的变量从其定义的角度覆盖作为参数传递或从环境继承的变量。
使用上面的示例,但使用不同的ENV
规范,可以在ARG
和ENV
指令之间创建更有用的交互:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
4 RUN echo $CONT_IMG_VER
与ARG
指令不同,ENV
值始终保留在生成的映像中。考虑不带--build-arg
标志的Docker构建:
$ docker build .
使用此Dockerfile示例,CONT_IMG_VER
它仍然保留在映像中,但其值将是指令v1.0.0
第3行中的默认设置ENV
。
在此示例中,变量扩展技术使您可以从命令行传递参数,并利用ENV
指令将其保留在最终映像中 。仅有限的一组Dockerfile指令支持变量扩展。
预定义的
Docker具有一组预定义ARG
变量,您可以在不使用ARG
Dockerfile中相应指令的情况下使用它们。
HTTP_PROXY
http_proxy
HTTPS_PROXY
https_proxy
FTP_PROXY
ftp_proxy
NO_PROXY
no_proxy
要使用它们,只需使用以下标志在命令行中传递它们:
--build-arg <varname>=<value>
默认情况下,这些预定义变量从的输出中排除 docker history
。排除它们可以降低意外泄露敏感身份验证信息到HTTP_PROXY
变量中的风险。
例如,考虑使用以下命令构建以下Dockerfile --build-arg HTTP_PROXY=http://user:pass@proxy.lon.example.com
FROM ubuntu
RUN echo "Hello World"
在这种情况下,HTTP_PROXY
变量的值在中不可用, docker history
也不被缓存。如果要更改位置,并且代理服务器已更改为http://user:pass@proxy.sfo.example.com
,则后续的构建不会导致高速缓存未命中。
如果您需要覆盖此行为,则可以通过ARG
在Dockerfile中添加如下语句来做到这一点:
FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"
构建此Dockerfile时,将HTTP_PROXY
保留在中 docker history
,并且更改其值会使构建缓存无效。
全球范围内的自动平台
仅当使用BuildKit后端时,此功能才可用。
Docker ARG
在执行构建的节点的平台(构建平台)和结果映像的平台(目标平台)上用信息预定义了一组变量。可以使用--platform
标志on 来指定目标平台docker build
。
以下ARG
变量是自动设置的:
-
TARGETPLATFORM
-构建结果的平台。例如linux/amd64
,linux/arm/v7
,windows/amd64
。 -
TARGETOS
-TARGETPLATFORM的OS组件 -
TARGETARCH
-TARGETPLATFORM的体系结构组件 -
TARGETVARIANT
-TARGETPLATFORM的变体组件 -
BUILDPLATFORM
-执行构建的节点的平台。 -
BUILDOS
-BUILDPLATFORM的OS组件 -
BUILDARCH
-BUILDPLATFORM的体系结构组件 -
BUILDVARIANT
-BUILDPLATFORM的变体组件
这些参数是在全局范围内定义的,因此在构建阶段或您的RUN
命令中不会自动提供。为了在构建阶段公开这些参数之一,请重新定义它而没有价值。
例如:
FROM alpine
ARG TARGETPLATFORM
RUN echo "I'm building for $TARGETPLATFORM"
对构建缓存的影响
ARG
变量不会像ENV
变量那样持久化到生成的映像中。但是,ARG
变量确实以类似的方式影响构建缓存。如果Dockerfile定义了一个ARG
其值不同于先前构建的变量,则首次使用时会发生“缓存未命中”,而不是其定义。特别是,RUN
一条指令之后的所有指令都 隐式地ARG
使用该ARG
变量(作为环境变量),因此可能导致高速缓存未命中。ARG
除非。中有匹配的ARG
语句,否则所有预定义变量均免于缓存Dockerfile
。
例如,考虑以下两个Dockerfile:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 RUN echo $CONT_IMG_VER
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 RUN echo hello
如果--build-arg CONT_IMG_VER=
在命令行上指定,则在两种情况下,第2行上的指定都不会导致高速缓存未命中。第3行确实会导致缓存未命中。ARG CONT_IMG_VER
导致RUN行被标识为与正在运行的CONT_IMG_VER=
echo hello 相同,因此,如果进行了`` 更改,则会遇到缓存未命中的情况。
考虑在同一命令行下的另一个示例:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER $CONT_IMG_VER
4 RUN echo $CONT_IMG_VER
在此示例中,高速缓存未命中发生在第3行。之所以发生未命中,是因为该变量在ENV
引用中的值引用了该ARG
变量,并且该变量通过命令行进行了更改。在此示例中,该ENV
命令使图像包含该值。
如果一条ENV
指令覆盖ARG
了同名指令,例如Dockerfile:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER hello
4 RUN echo $CONT_IMG_VER
第3行不会导致缓存未命中,因为的值CONT_IMG_VER
是一个常量(hello
)。结果,RUN
(第4行)使用的环境变量和值在两次构建之间不会改变。
ONBUILD
ONBUILD [INSTRUCTION]
该ONBUILD
指令将映像用作另一个构建的基础时,将在以后的时间向该映像添加触发指令。该触发器将在下游构建的上下文中执行,就好像它已FROM
在下游指令之后立即插入 Dockerfile
。
任何构建指令都可以注册为触发器。
如果要构建的图像将用作构建其他图像的基础,例如应用程序构建环境或可以使用用户特定配置自定义的守护程序,则此功能很有用。
例如,如果您的映像是可重用的Python应用程序构建器,则将需要在特定目录中添加应用程序源代码,并且此后可能需要调用构建脚本 。你不能只是打电话ADD
和RUN
现在,因为你还没有访问应用程序的源代码,这将是为每个应用程序生成不同的。您可以简单地为应用程序开发人员提供Dockerfile
可复制粘贴到其应用程序中的样板,但这效率低下,容易出错且难以更新,因为它与特定于应用程序的代码混合在一起。
解决方案是使用ONBUILD
注册预先的指令以在下一个构建阶段中稍后运行。
运作方式如下:
- 当遇到
ONBUILD
指令时,构建器将触发器添加到正在构建的图像的元数据中。该指令不会影响当前版本。 - 构建结束时,所有触发器的列表都存储在映像清单的key下
OnBuild
。可以使用docker inspect
命令检查它们。 - 稍后,可以使用该
FROM
指令将该图像用作新版本的基础 。作为处理FROM
指令的一部分,下游构建器将查找ONBUILD
触发器,并按照注册时的顺序执行它们。如果任何触发器失败,则该FROM
指令将中止,进而导致构建失败。如果所有触发器都成功,则FROM
指令完成,并且构建照常继续。 - 执行完触发器后,将从最终图像中清除触发器。换句话说,它们不是“孙子代”版本所继承的。
例如,您可以添加以下内容:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
警告:不允许
ONBUILD
使用链接说明ONBUILD ONBUILD
。
警告:该
ONBUILD
指令可能不会触发FROM
或执行MAINTAINER
。
STOPSIGNAL
STOPSIGNAL signal
该STOPSIGNAL
指令设置将被发送到容器退出的系统调用信号。该信号可以是与内核syscall表中的位置匹配的有效无符号数字(例如9),也可以是SIGNAME格式的信号名称(例如SIGKILL)。
HEALTHCHECK
该HEALTHCHECK
指令有两种形式:
-
HEALTHCHECK [OPTIONS] CMD command
(通过在容器内部运行命令来检查容器的运行状况) -
HEALTHCHECK NONE
(禁用从基本映像继承的任何运行状况检查)
该HEALTHCHECK
指令告诉Docker如何测试容器以检查其是否仍在工作。这样可以检测到诸如Web服务器陷入无限循环并且无法处理新连接的情况,即使服务器进程仍在运行。
指定容器的运行状况检查后,除了其正常状态外,它还具有运行状况。此状态最初为starting
。只要运行状况检查通过,它将变为healthy
(以前处于任何状态)。在一定数量的连续失败之后,它变为unhealthy
。
之前可能出现的选项CMD
是:
-
--interval=DURATION
(默认值:30s
) -
--timeout=DURATION
(默认值:30s
) -
--start-period=DURATION
(默认值:0s
) -
--retries=N
(默认值:3
)
运行状况检查将首先在容器启动后的间隔秒数内运行,然后在每次之前的检查完成后的间隔秒数内再次运行。
如果单次检查花费的时间超过超时秒数,则认为检查失败。
对于要考虑的容器,需要重试连续进行的运行状况检查失败unhealthy
。
开始时间段为需要时间进行引导的容器提供了初始化时间。在此期间的探针故障将不计入最大重试次数。但是,如果运行状况检查在启动期间成功,则认为该容器已启动,并且所有连续失败将计入最大重试次数。
HEALTHCHECK
Dockerfile中只能有一条指令。如果您列出多个,则只有最后一个HEALTHCHECK
才会生效。
CMD
关键字之后的命令可以是shell命令(例如HEALTHCHECK CMD /bin/check-running
)或exec数组(与其他Dockerfile命令一样;ENTRYPOINT
有关详细信息,请参见例如)。
该命令的退出状态指示容器的健康状态。可能的值为:
- 0:成功-容器健康且可以使用
- 1:不健康-容器无法正常工作
- 2:保留-请勿使用此退出代码
例如,要每五分钟检查一次,以便网络服务器能够在三秒钟内为站点的主页提供服务:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
为了帮助调试失败的探针,命令在stdout或stderr上写入的任何输出文本(UTF-8编码)将存储在运行状况中,并可以通过查询 docker inspect
。此类输出应保持简短(当前仅存储前4096个字节)。
当容器的健康状态发生变化时,将health_status
生成具有新状态的事件。
该HEALTHCHECK
功能已在Docker 1.12中添加。
SHELL
SHELL ["executable", "parameters"]
该SHELL
指令允许覆盖用于命令的shell形式的默认shell 。在Linux上["/bin/sh", "-c"]
,默认的shell是,在Windows 上,默认的shell 是["cmd", "/S", "/C"]
。该SHELL
指令必须以JSON格式编写在Dockerfile中。
该SHELL
指令在Windows上特别有用,在Windows上有两个常用且完全不同的本机shell:cmd
和powershell
,以及可用的替代shell包括sh
。
该SHELL
说明可以出现多次。每个SHELL
指令将覆盖所有先前的SHELL
指令,并影响所有后续的指令。例如:
FROM microsoft/windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello
以下说明可以通过影响SHELL
指令时, 壳他们的形式在一个Dockerfile使用:RUN
,CMD
和ENTRYPOINT
。
以下示例是Windows上常见的模式,可通过使用SHELL
指令进行精简:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
docker调用的命令将是:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
这效率低下有两个原因。首先,有一个不必要的cmd.exe命令处理器(也称为外壳程序)被调用。其次,shell 形式的每条RUN
指令都需要在命令前加上前缀。powershell -command
为了使其更有效,可以采用两种机制之一。一种是使用RUN命令的JSON形式,例如:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
尽管JSON形式是明确的,并且不使用不必要的cmd.exe,但它确实需要通过双引号和转义来实现更多的详细信息。另一种机制是使用SHELL
指令和外壳程序形式,使Windows用户的语法更加自然,尤其是与escape
parser指令结合使用时:
# escape=`
FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
导致:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
---> Running in 6fcdb6855ae2
---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
---> Running in d0eef8386e97
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/28/2016 11:26 AM Example
---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
---> Running in be6d8e63fe75
hello world
---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>
该SHELL
指令还可用于修改外壳的操作方式。例如,SHELL cmd /S /C /V:ON|OFF
在Windows上使用,可以修改延迟的环境变量扩展语义。
如果SHELL
需要备用shell,例如,和其他zsh
,该指令也可以在Linux上使用。csh``tcsh
该SHELL
功能已在Docker 1.12中添加。
如需进一步了解 配置详情 参考官方文档 https://docs.docker.com/engine/reference/builder/
网友评论