我最近一直在使用Docker来托管一个RStudio服务器实例。有许多软件包需要安装,在Dockerfile中执行此操作的一种方法就是这样(显然有更多行):
RUN Rscript -e "install.packages('beanplot')"
RUN Rscript -e "install.packages('beeswarm')"
RUN Rscript -e "install.packages('boot')"
RUN Rscript -e "install.packages('caTools')"
我看到许多情况都是这样做的:
RUN Rscript -e "install.packages(c('beanplot','beeswarm','boot','caTools'))
另外,我经常会看到各种可执行行链接在一起:
RUN yum -y update \
&& yum -y groupinstall 'Development Tools' \
&& yum -y install epel-release \
vim \
initscripts \
libpng-devel \
mesa-libGL \
mesa-libGL-devel \
mesa-libGLU \
mesa-libGLU-devel \
ypbind \
rpcbind \
authconfig \
&& yum -y install R \
&& mkdir /rhome
而不是和&&作为单独的RUN行。
我认为好处是减少了泊坞窗图像的大小,但是当我测试一个大型示例时,任何一种方法都会产生相同的大小。
链接命令的优点是什么,而不是为每一行提供单独的RUN命令?
答案 0 :(得分:3)
每个RUN
命令都会向图像添加一个新图层,并且允许的图层数上限(大约255左右)。出于性能原因强制执行此限制。
每次在容器内运行的应用程序需要访问文件时,引擎会从上到下搜索所有这些层中的文件,直到找到它为止。如果应用程序尝试更改不在最顶层的文件,则引擎首先在最顶层创建该文件的副本,然后将应用程序的写请求处理到副本上。
最顶层是可写的。它不存储在图像中,但它是容器的一部分。存储在图像中的图层是只读的。
documentation中对此进行了解释。建议small number of layers保留best practice。