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是Dockerfile中唯一可以在FROM之前的指令。请看了解ARG和FROM的交互方式。

FROM可以在一个Docker文件中多次出现,以创建多个镜像,或将一个构建阶段作为另一个的依赖。在每条新的FROM指令之前,只需记下提交所输出的最后一个镜像ID。每条FROM指令都会清除之前指令创建的任何状态。

可以通过在FROM指令中添加AS名称来给新的构建阶段起一个名字。这个名字可以在随后的FROM和COPY --from=<name>指令中使用,以指代在这个阶段建立的图像。

标签或摘要的值是可选的。如果你省略了其中任何一个,构建器默认会假定一个最新的标签。如果构建器找不到标签值,会返回一个错误。

可选的--platform标志可以用来指定图像的平台,以防FROM引用一个多平台的图像。例如,linux/amd64,linux/arm64,或者windows/amd64。默认情况下,会使用构建请求的目标平台。全局构建参数可以用在这个标志的值中,例如自动平台ARG允许你强制一个阶段为本地构建平台(--platform=$BUILDPLATFORM),并使用它来交叉编译到阶段内的目标平台。

理解ARG和FROM的相互作用

FROM指令支持由第一个FROM指令之前的任何ARG指令所声明的变量。

ARG CODE_VERSION=latest

FROM base:${CODE_VERSION}。

CMD /code/run-app

从extra:${CODE_VERSION}中获取。

CMD /code/run-extras

在FROM之前声明的ARG是在构建阶段之外的,所以它不能在FROM之后的任何指令中使用。要使用在第一个FROM之前声明的ARG的缺省值,请在构建阶段内使用一个没有值的ARG指令。

ARG VERSION=latest

FROM busybox:$VERSION

ARG VERSION

RUN echo $VERSION > image_version

    • RUN

RUN有2种形式。

RUN <command> (shell形式,命令在shell中运行,在Linux中默认为/bin/sh -c,在Windows中为cmd /S /C)

RUN ["executable", "param1", "param2"] (exec形式)

RUN指令将在当前映像之上的一个新层中执行任何命令,并提交结果。产生的提交镜像将用于Docker文件的下一步。

分层的RUN指令和生成的提交符合Docker的核心概念,即提交很便宜,容器可以从镜像历史上的任何一点创建,很像源代码控制。

exec形式使得避免shell字符串混杂成为可能,并且可以使用不包含指定shell可执行文件的基础镜像来RUN指令。

shell形式的默认shell可以用SHELL命令来改变。

在shell形式中,你可以使用反斜杠(backslash)将一条RUN指令延续到下一行。例如,考虑这两行。

RUN /bin/bash -c 'source $HOME/.bashrc; \\

echo $HOME'

它们一起相当于这一行。

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' 。

要使用一个不同的shell,而不是'/bin/sh',使用exec形式,输入所需的shell。比如说。

RUN ["/bin/bash", "-c", "echo hello"]

注意事项

执行表格被解析为一个JSON数组,这意味着你必须在单词周围使用双引号(")而不是单引号(')。

与shell形式不同,exec形式并不调用命令shell。这意味着正常的shell处理不会发生。例如,RUN [ "echo", "$HOME" ] 不会对$HOME进行变量替换。如果你想进行shell处理,那么要么使用shell形式,要么直接执行一个shell,例如。RUN [ "sh", "-c", "echo $HOME" ] 。当使用exec形式并直接执行shell时,就像shell形式的情况一样,是shell在做环境变量的扩展,而不是docker。

注意

在JSON形式中,有必要转义反斜线。这在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和COPY指令失效。

    • CMD

一个Docker文件中只能有一条CMD指令。如果你列出一个以上的CMD,那么只有最后一个CMD会生效。

CMD的主要目的是为一个正在执行的容器提供默认值。这些默认值可以包括一个可执行文件,

也可以省略可执行文件,在这种情况下,你必须同时指定一个ENTRYPOINT指令。

exec形式被解析为JSON数组,这意味着你必须在单词周围使用双引号("),而不是单引号(')。

与shell形式不同,exec形式不调用命令shell。这意味着正常的shell处理不会发生。

例如,CMD [ "echo", "$HOME"] 不会对$HOME进行变量替换。

如果你想进行shell处理,那么要么使用shell形式,要么直接执行一个shell,

例如。CMD [ "sh", "-c", "echo $HOME" ] 。

当使用exec形式并直接执行shell时,就像shell形式的情况一样,是shell在进行环境变量的扩展,而不是docker。

如果你使用CMD的shell形式,那么<command>将在/bin/sh -c中执行。

如果你想在没有shell的情况下运行你的<命令>,那么你必须将命令表达为一个JSON数组,并给出可执行文件的完整路径。

这种数组形式是CMD的首选格式。任何额外的参数必须在数组中单独表示为字符串。

如果用户指定参数给docker run,那么它们将覆盖CMD中指定的默认值。

不要把RUN和CMD混淆。RUN实际上是运行一个命令并提交结果;CMD在构建时不执行任何东西,但为图像指定预定的命令。

    • LABEL

每一个对象都包含相应的元数据信息,比如 Docker 镜像就包含作者、大小等等元数据信息。

在使用镜像的时候,往往会通过这些元数据信息来查找适合的镜像来用于开发或测试,而不单单只是通过名字去检索。

"Labels": {

"env": "test",

"org.label-schema.build-date": "20201204",

"org.label-schema.license": "GPLv2",

"org.label-schema.name": "CentOS Base Image",

"org.label-schema.schema-version": "1.0",

"org.label-schema.vendor": "CentOS",

"version": "1.0"

}

docker image ls --filter "label=env=test"

########################################################

MAINTAINER 已废弃

MAINTAINER指令设

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值