构建时可以是 docker 层 "bypassed" 吗?

Can be a docker layer "bypassed" on build?

假设我有一个这样的 Dockerfile:

FROM debian:stretch

RUN apt update
RUN apt install -y wget 

RUN wget https://whosebug.com/
# I know the wget is useless. Is just an example :)
CMD ["echo", "hello-world"]

我想覆盖 wget 语句,一个新的 运行 语句。改完之后,当我rebuild的时候,它会重新运行我修改后的所有命令,所以wget会重新执行。问题是 wget 命令需要很长时间才能完成,因为在我的真实文件中,该文件是一个非常大的文件。

问题是,可以docker "tweaked"在某处避免再次构建wget层的执行吗?如果我已经构建了它,该层是否可以再次使用甚至更改其上的语句?

谢谢。

据我所知,这是不可能的,因为 docker 只会重用图层直到您更改并从那里开始重新构建。

这是因为新层在先前构建的层上进行了测试(因此您的 RUN wget 层在 FROMRUN apt install -y wget 的层上进行了测试和构建)。因此,如果您在 RUN wget 指令上方输入另一个 RUN 指令,您的 RUN wget 指令的环境会发生变化,因此需要再次执行。

我认为没有办法手动处理它,因此它会重用在 "different" 环境中构建的层,我也不推荐它。

使用 docker-compose,或在 运行 docker run 时使用 -v 标志,您可以安装一个将在两次运行之间持续存在的卷。将您的 wget 更改为在没有文件的情况下有条件地运行的脚本。

这不会缓存后面的内容,但会使该步骤更快。

您可能需要修改存储该文件的文件夹,具体取决于脚本的其余部分以及环境的设置方式。

我在这里使用 compose 进行卷安装:https://github.com/jaydorsey/ghgvcR/blob/master/docker-compose.yml

查看该存储库中的 bin/download-files.sh 文件以获得 bash 示例。