将ARG放在Dockerfile的顶部会阻止层重用吗?

时间:2017-01-11 14:11:29

标签: docker dockerfile

如果在Dockerfile顶部声明的ARG被更改,但其值仅用于Dockerfile末尾附近的RUN命令,Docker是否从头开始重建整个图像,或者它是否能够重新生成在相关的RUN命令之前使用中间图像?

为了更好地利用分层,我应该将我的ARG声明放在Dockerfile的顶部,还是在使用它们的部分之前?

我想我的一部分问题是ARG指令是否会生成一个中间层。

2 个答案:

答案 0 :(得分:10)

如果更改构建参数的值,则该ARG行之后的所有图层都将失效。所以我想你应该在使用ARG之前加入它。

就在你需要之前:

 docker build --build-arg TEST_ARG=test .
 Sending build context to Docker daemon 2.048 kB
 Step 1 : FROM ubuntu
 ---> 104bec311bcd
 Step 2 : RUN echo "no arg used"
 ---> Using cache
 ---> 5c29cb363a27
 Step 3 : ARG TEST_ARG
 ---> Using cache
 ---> 73b6080f973b
 Step 4 : RUN echo $TEST_ARG
 ---> 0acd55c24441
 Successfully built 0acd55c24441

在顶部:

docker build --build-arg TEST_ARG=test .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM ubuntu
 ---> 104bec311bcd
Step 2 : ARG TEST_ARG
---> Using cache
---> b611a1023fe3
Step 3 : RUN echo "no arg used"
---> Running in 63e0f803c6b2
no arg used
---> 592311ccad72
Removing intermediate container 63e0f803c6b2
Step 4 : RUN echo $TEST_ARG
---> Running in 1515aa8702f0
test
---> fc2d850fbbeb
Removing intermediate container 1515aa8702f0
Successfully built fc2d850fbbeb

在第一个示例中,从缓存中使用了两个层,而在第二个示例中,只使用了一个层(有趣的是,ARG层本身)来自缓存。

答案 1 :(得分:0)

要比接受的响应更精确,并非在ARG声明后所有行都将缓存无效。仅使用ARG值和RUN的那些。 docker文档已被修改以处理ARG缓存无效: https://github.com/moby/moby/issues/18017https://github.com/moby/moby/pull/18161,然后在此处运行解释更准确https://github.com/moby/moby/pull/21885和官方文档https://docs.docker.com/engine/reference/builder/#impact-on-build-caching

  

Blockquote   对构建缓存的影响   ARG变量不会像ENV变量那样持久保存到生成的映像中。但是,ARG变量确实以类似的方式影响构建缓存。如果Dockerfile定义了一个值与先前版本不同的ARG变量,则首次使用时会发生“缓存未命中”,而不是其定义。特别是,所有在ARG指令之后的RUN指令都隐式使用ARG变量(作为环境变量),因此可能导致高速缓存未命中。除非Dockerfile中有匹配的ARG语句,否则所有预定义的ARG变量均免于缓存。

是的,我想您必须将args移到不需要参数的RUN下才能保持层缓存的最佳状态。

相关问题