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

时间:2014-12-13 09:56:01

标签: deployment continuous-integration workflow docker

作为Vagrant用户,在尝试使用Docker时,我发现开发工作流与Vagrant和Docker之间存在一个显着差异 - 使用Docker我需要每次从头开始重建我的图像,即使我在代码中进行了微小的更改。

对我来说这是一个主要问题,因为图像重建过程通常非常冗余且耗时。

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

4 个答案:

答案 0 :(得分:2)

正如Mark O'Connor所说,其中一个提示可能是为您的容器构建基本图像。此映像应具有依赖项,程序包安装,下载...或任何其他消耗活动。应该假设该基础图像的构建频率低于其他图像。以类似的方式,如果dockerfile的每个步骤的最终执行状态没有改变,Docker不会再次构建此层。因此,您可以尝试执行命令,而不是几乎每次运行都可以更改此状态(例如:apt-get update),因此docker不必重建之前的步骤。此外,您可以尝试在后续步骤中编辑dockerfiles,而不是第一次。

如果您在容器内编译/下载内容,则另一个选项是将其下载或编译到主机文件夹中,并使用-v中的--volumedocker run选项将其附加到容器中}。

最后,还有其他方法解决了这个问题,就像厨师用knife container一样。在这种方法中,您使用厨师烹饪书构建容器,并且每次构建它(因为您已经编辑了烹饪书......)这些更改将作为新的泊坞窗层(AUFS层)应用,您不必重复所有这个过程。我不建议使用此解决方案,除非您有Chef的经验并且您有烹饪工具来管理您的软件。您应该更加努力地工作,如果您希望Chef只管理docker容器,我认为它不值得(尽管Chef是管理基础架构的绝佳选择)。

要自动化构建过程,以防您拥有多个图像依赖项,您可以使用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

答案 1 :(得分:2)

我为vagrant-cachier插件提交了一个功能请求,用于保存docker构建数据,并为该进程附加了一个bash解决方法。如果您可以自己解决问题,可以在vagrant中实现脚本。

caching docker build data with vagrant

请注意,此过程需要安装vagrant-cachier插件,如果他们是计算机新手,则必须从磁盘保存并加载+ 300MB文件。因此,如果您的dockerfiles只有1-5行代码,那么它真的很慢,但是如果您的dockerfiles有很多LOC或者必须从网上下载的图像,它会很快。

另请注意,此方法可以节省每个中间构建步骤。因此,如果要构建映像并在dockerfile中间更改一行并再次构建,则docker构建过程将获取所有缓存的中间容器,直到更改的行。

使用baseimages仍然是首选方法,但您可以将两种程序结合使用。

随意发布改进和订阅,以便fgrehm可以在他的插件本地实现这一点。

答案 2 :(得分:0)

有一些技巧可能会改善您的工作流程(非常注重网络)

Docker缓存

始终确保在最后将您的源添加到Dockerfile中的Docker镜像。 实施例;

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

COPY data/ /data

这将确保在构建映像时获得最佳缓存,并且在更改源代码时Docker不必重建npm包。

另外,请确保您没有添加经常更改的文件夹/文件的基本图片(例如基本图片正在执行COPY . /data/

无花果山

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

开发服务器

您可以在开发时启动开发人员Web服务器,在不开发时启动nginx(如果您正在开发www应用程序,但同样的想法适用于其他应用程序)。

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

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

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

自动刷新应用

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

如果您正在使用if [[ $DEBUG ]] ...技巧,请让他们在与普通实例(nginx)相同的端口上进行侦听。这样,您可以为您的反向代理配置1个配置,即只将流量发送到示例www:8080,它将在生产中和您正在开发的时间点击您的网页。

答案 3 :(得分:0)

创建一个基础图像,其中包含大部分应用程序的依赖项。这将显着减少您的泊坞窗构建时间。