代码之家  ›  专栏  ›  技术社区  ›  Python Dev

docker为什么兑现回显日期和回显日期>>/timestamp.txt

  •  0
  • Python Dev  · 技术社区  · 1 年前

    我有docker compose和Dockerfile:

    ...
    RUN echo date
    RUN echo date >> /timestamp.txt
    ...
    

    当我删除图像并尝试再次创建它时,我会收到以下消息:

    #5 [spring-boot-app stage-0 6/9] RUN echo date
    #5 CACHED
    
    #6 [spring-boot-app stage-0 7/9] RUN echo date >> /timestamp.txt
    #6 CACHED
    
    

    正如我所理解的,docker不应该改变结果的CACHE命令,不是吗?

    我试图在Dockerfile中生成随机结果的命令,并期望docker不会缓存它。

    2 回复  |  直到 1 年前
        1
  •  4
  •   David Maze    1 年前

    Docker的层缓存仅基于两件事:

    1. 上一层是否已缓存?
    2. 如果是,那么这是吗 RUN 命令是否与以前缓存的命令相同?

    在您的示例中 运行 命令是幂等的:它总是创建一个名为 timestamp.txt 包含单个单词 date Docker无法轻易区分这与跑步之间的区别 date >/timestamp.txt ; 只是跑步 日期 ,这不会影响容器文件系统;或者运行构建命令时可能发生的情况 make .

    作为一个推论,你通常应该安排 运行 命令使得它们确实从相同的输入生成相同的结果。例如,不要 RUN git clone ,如果上游存储库更新,它不会注意到。

    COPY ing文件也会影响层缓存。如果缓存了上一层,则 副本 将相同的文件放入图像中会生成缓存的图像。这意味着,如果您更改包管理器锁定文件之类的内容( package-lock.json , yarn.lock , mix.lock , go.mod , requirements.txt )它将导致下一个 运行 命令,该命令实际执行要重新运行的安装。

    原则上你可以 docker build --no-cache 以避免层缓存,但这不应该是您常规需要的东西。

        2
  •  0
  •   Tedpac    1 年前

    第一,跑步 $ echo date 和跑步不一样 $ echo $(date) $ echo `date` 。第一个命令(您正在使用的命令)打印文字单词“date”,而最后两个命令打印当前时间戳。

    其次,作为Docker的黄金法则,您应该始终尝试实现 Dockerfile 通过这种方式,您从中构建的映像可以在不同的场景或平台上复制(例如,确保这一点的一种方法是指定依赖项的版本)。如果你不尝试遵循这个规则,你有时会遇到意想不到的结果,尤其是因为Docker缓存的工作方式。

    最后,更具体地说 Docker documentation 说:

    的缓存 RUN 之间的指令不会自动失效 构建。

    这意味着您必须应用策略来强制重新执行 运行 说明(我留下的链接提到了几种这样的策略)。

    但为什么呢? 因为否则Docker将不得不执行 运行 指令来知道相应的图像层是否发生了变化,这只会破坏缓存的目的。