場景
看到很多 Dockerfile
都是把 apt-get update
和 apt-get install
寫在同一個 RUN
指令中的
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
package-foo
而不是
RUN apt-get update
RUN apt-get install -y \
package-bar \
package-baz \
package-foo
只知道這樣寫在同一個 RUN
中會減少 layer
層黍匾,縮減構(gòu)建鏡像的大小.
但看到有一些文章提到褐筛,只有寫在同一個 RUN
中才會對后面的 apt-get install
生效删豺,卻沒有細(xì)說原因.
因此產(chǎn)生了一個疑惑逗嫡,分開寫也應(yīng)該會對后面的 apt-get install
生效才對啊师坎,因為鏡像的構(gòu)建是一層一層的僵闯,后面的層會基于前面的層.
也就是說霜大,RUN apt-get update
會單獨構(gòu)建一層围橡,并且會對后面 RUN apt-get install
的層產(chǎn)生作用才對.
分析
假設(shè)有一個這樣的 Dockerfile
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y curl
構(gòu)建鏡像之后,所有的層都會在 Docker 的緩存中.
假設(shè)后來修改 apt-get install
添加額外的包
FROM ubuntu:14.04
RUN apt-get update
RUN apt-get install -y curl nginx
Docker 將初始和修改的指令視為相同榄融,并會重用之前構(gòu)建的緩存.
因此参淫,不會執(zhí)行 apt-get update
,因為構(gòu)建直接使用之前的緩存版本.
由于 apt-get update
沒有運(yùn)行愧杯,所以構(gòu)建安裝的 curl
和 nginx
包很可能是過時的版本.
所以涎才,把 apt-get update
和 apt-get install
寫在同一個 RUN
中以獲取最新版本的包,而且還減少了 layer
層.