【问题标题】:"RUN true" in dockerfiledockerfile 中的“RUN true”
【发布时间】:2022-08-11 12:58:43
【问题描述】:

当我接手一个项目时,我在 Dockerfile 中发现了一个命令“RUN true”。

FROM xxx

RUN xxx
RUN true
RUN xxx

我不知道这个命令是做什么的,谁能帮忙解释一下。在我看来,这个命令没有意义,但我不确定是否还有其他用途。

有关于Creating Images 的文档,你可以看到它:

RUN true \\
    && dnf install -y --setopt=tsflags=nodocs \\
        httpd vim \\
    && systemctl enable httpd \\
    && dnf clean all \\
    && true

@大卫迷宫

测试它。码头文件:

FROM centos:7.9.2009

RUN yum install tmux -y

RUN yum install not_exists -y

构建日志:

Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos:7.9.2009
 ---> eeb6ee3f44bd
Step 2/3 : RUN yum install tmux -y
 ---> Running in 6c6e29ea9f2c
...omit...
Complete!
Removing intermediate container 6c6e29ea9f2c
 ---> 7c796c2b5260
Step 3/3 : RUN yum install not_exists -y
 ---> Running in e4b7096cc42b
...omit...
No package not_exists available.
Error: Nothing to do
The command \'/bin/sh -c yum install not_exists -y\' returned a non-zero code: 1

修改dockerfile:

FROM centos:7.9.2009

RUN yum install tmux -y

RUN yum install tree -y

构建日志:

Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos:7.9.2009
 ---> eeb6ee3f44bd
Step 2/3 : RUN yum install tmux -y
 ---> Using cache
 ---> 7c796c2b5260
Step 3/3 : RUN yum install tree -y
 ---> Running in 180b32cb44f3
...omit...
Installed:
  tree.x86_64 0:1.6.0-10.el7

Complete!
Removing intermediate container 180b32cb44f3
 ---> 4e905ed25cc2
Successfully built 4e905ed25cc2
Successfully tagged test:v0

你可以看到Using cache 7c796c2b5260。没有命令 \"RUN true\",但第一个 \"RUN\" 缓存被重用。

    标签: dockerfile


    【解决方案1】:

    RUN true 作为一个独立的命令绝对没有任何作用,删除它是安全的。

    /bin/truestandard shell command。它不读取输入,不产生输出,既不读取也不写入文件;它只是以状态码 0(“成功”)退出。除了在docker history 中插入一个附加层之外,将其作为 Docker 步骤运行不会对最终图像产生任何影响。

    我能想到的一个聪明的用途是让 Dockerfile 的后面部分重新运行。想象一个像

    RUN some_expensive_command http://server-a.example.com/input1
    RUN another_expensive_command http://server-b.example.com/input2
    

    如果第二个输入发生变化,您可能需要重建此图像。不过,docker build --no-cache 也将重新运行第一步,这可能需要比您想要的更长的时间。在两行之间插入RUN true 行会破坏 Docker 的层缓存,但只有在第一个命令运行之后。

    # identical RUN line as before, from cache
    RUN some_expensive_command http://server-a.example.com/input1
    # not the same RUN line, so "executes" (but does nothing)
    RUN true
    # not running commands from cache any more
    RUN another_expensive_command http://server-b.example.com/input2
    

    【讨论】:

    • 只是好奇为什么 RUN input1 会在第二种情况下被缓存,而不是在第一种情况下,如果它没有改变?谢谢
    • 假设您运行一次docker build,它会执行这两个步骤。现在你再次运行docker build 而不更改 Dockerfile,这两个层都将来自缓存。您可以使用docker build --no-cache,并且这两个层都不会来自缓存,但第一步可能运行起来很昂贵。插入人工的RUN true 命令可以让您运行普通的docker build(没有--no-cache)从缓存中获取第一步,而不是第二步。
    • 啊,这很聪明,谢谢你的解释
    • 我对其进行了测试,没有RUN true,缓存也可以工作。我已经写了我的问题。
    【解决方案2】:

    我找到了一个已经存在的answer,它很好地解释了它。

    如果我在这里引用答案:

    运行并因此创建一个新容器,即使它终止,仍然会保留生成的容器图像和元数据,这些图像和元数据仍然可以链接到。

    因此,当您运行 docker run ... /bin/true 时,您实际上是在创建一个用于存储目的的新容器并运行最简单的东西。

    在 Docker 1.5 中引入了 docker create 命令,所以我相信您现在可以“创建”容器,而不会混淆运行 /bin/true 之类的东西

    我在“#chaining-commands”部分下的best practices github page 中找到了一个快速解释:

    块的第一个和最后一个命令是特殊的。

    如果您想在块中添加或附加单行命令,则必须编辑两行 - 您正在添加的一行以及第一个或最后一个命令。第一个命令与 RUN 指令位于同一行,而最后一个命令缺少尾部反斜杠。

    使用您不想更改的命令编辑一行存在引入错误的风险,并且您还掩盖了该行的历史记录。这可以通过让第一个和最后一个命令都为真来缓解——它们什么都不做。

    【讨论】:

    • 它使 git 历史更清晰,好主意!
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2021-03-02
    • 2020-03-09
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多