在开发过程中重build图像时如何避免冗余和时间损失?

作为一名Vagrant用户,在尝试Docker时,我注意到了开发工作stream与Vagrant和Docker之间的一个重大区别 – 用Docker,我需要从头开始重build我的映像,即使我在代码中做了细微的更改。

这对我来说是个大问题,因为重build图像的过程往往非常冗余和耗时。

也许有一些Docker已经发明了一些聪明的工作stream程,如果是这样的话,它们是什么?

我为vagrant-cachier插件提交了一个function请求,用于保存docker构build数据,并为该进程附加了一个bash解决方法。 如果你可以绕过自己,你可以在stream浪汉中实现脚本。

caching泊坞窗与stream浪者build立数据

请注意,这个程序需要安装vagrant-cachier插件,如果它们是新机器,则必须从磁盘保存和加载+ 300MB文件。 因此,如果你的dockerfiles只有1-5行代码,那么速度真的很慢,但是如果你有很多LOC或者需要从网上下载的图片的dockerfiles,

另外请注意,这种方法可以节省每一个中间build筑步骤 因此,如果您正在构build一个图像,并在dockerfile中更改一行,然后再次构build,docker构build过程将获取所有caching的中间容器,直到更改后的行。

使用baseimages仍然是首选的方法,但是你可以结合这两个程序。

随意张贴改进和订阅,所以fgrehm可能会实现在他的插件本地。

正如马克·奥康纳(Mark O'Connor)所build议的,其中一个提示可能是为您的容器build立一个基础图像。 这个图像应该有依赖关系,软件包安装,下载…或任何其他消费活动。 应该认为这个基础图像比其他人更less。 以类似的方式,如果dockerfile的每个步骤的执行的最终状态不会更改,Docker不会再次构build此图层。 因此,你可以尝试执行命令,而不是每次运行几乎每次都可能改变这个状态(例如:apt-get update),所以docker不必重build以前的步骤。 而且你也可以尝试在后面的步骤中编辑你的dockerfiles比第一个更好。

另一个select,如果你编译/下载容器内的东西是让它下载或编译在一个主机文件夹,并附加到容器使用-v--volume选项在docker run

最后还有其他解决这个问题的方法,就像厨师用刀具容器一样 。 在这种方法中,您使用厨师食谱来构build容器,并且每次构build容器时(因为您已经编辑了食谱…),这些更改将作为新的docker层(AUFS层)应用,您不必重复所有这个过程。 我不推荐这个解决scheme,除非你有厨师的经验,你有食谱来pipe理你的软件。 你应该更努力地工作,如果你只想要厨师来pipe理docker集装箱,我认为这不值得(尽pipe厨师是pipe理基础设施的一个很好的select)。

如果你自己有几个图像依赖项,为了自动化构build过程,你可以使用一个bash脚本来帮助你完成这个任务(信任到smola @ github ):

 #!/bin/bash IMAGES="${IMAGES:-stratio/base:test stratio/mesos:test stratio/spark-mesos:test stratio/ingestion:test}" LATEST_TAG="${LATEST_TAG:-test}" for image in $IMAGES ; do USER=${image/\/*/} aux=${image/*\//} NAME=${aux/:*/} TAG=${aux/*:/} DIR=${NAME}/${TAG} pushd $DIR docker build --tag=${USER}/${NAME}:${TAG} . if [[ $TAG = $LATEST_TAG ]] ; then docker tag ${USER}/${NAME}:${TAG} ${USER}/${NAME}:latest fi popd done 

有一些技巧可能会改善您的工作stream程(非常关注networking)

Dockercaching

一定要确保你最终将你的源码添加到Dockerfile中的Docker镜像中。 例;

 COPY data/package.json /data/ RUN cd /data && npm install COPY data/ /data 

这将确保在构build映像时获得最佳caching,并且在更改源代码时,Docker不必重新生成npm包。

此外,请确保没有添加经常更改的文件夹/文件的基本映像(如执行COPY . /data/

无花果山

使用fig(或其他工具),并在开发时安装你的源代码目录。 这样,您可以开发即时更改,并在构build图像时仍然使用当前版本的代码。

开发服务器

您可以在开发时启动开发者Web服务器,如果您正在开发WWW应用程序,则可以启动您的开发者Web服务器。

例如,在启动脚本中,执行如下操作:

 if [[ $DEBUG ]]; then /usr/bin/supervisorctl start gulp else /usr/bin/supervisorctl start nginx fi 

在你的supervisord.conf文件中有autostart=false

自动刷新应用程序

如果您正在开发Web应用程序,请使用诸如gulpgulp-connect类的工具,如果您正在开发python / django应用程序,请使用runserver实用程序。 检测到文件中的更改时都会重新加载服务器。

如果你正在使用if [[ $DEBUG ]] ...技巧,让他们监听与你的普通实例(nginx)相同的端口。 这样,你可以为你的反向代理configuration1个,也就是说,只需要将stream量发送到示例www:8080 ,它将在生产和开发过程中击中你的网页。

创build一个包含应用程序依赖项大部分的基础映像。 这将显着减less您的docker构build时间。