docker添加caching当git签出相同的文件

我需要CI服务器构build映像重用dockercaching结帐项目。

当签出同一个文件时,Docker ADD不使用caching。

我在git分支执行docker build -t somename . 它通常使用dockercaching,但如果我通过git checkout B去分支B ,什么也不做,通过git checkout A去分支git checkout A ,再次运行docker build -t somename . dockercaching仅在第一个ADD之前使用。

这里的例子:

Dockerfile

 # DOCKER-VERSION 0.10.0 FROM myregistry:5000/ruby:2.1.2-1 MAINTAINER ME # Gem sources RUN gem source -r https://rubygems.org/ RUN gem source -a http://gems.mydomain # Never install a ruby gem docs RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc # gems install RUN mkdir /foo WORKDIR /foo RUN gem install bundler ADD Gemfile /foo/Gemfile RUN bundle install # expose ports EXPOSE 8080 

从构build日志

 Sending build context to Docker daemon 19.54 MB Sending build context to Docker daemon Step 0 : FROM myregistry:5000/ruby:2.1.2-1 ---> 9ce683a713b4 Step 1 : MAINTAINER ME ---> Using cache ---> 8f54114fd2e7 Step 2 : RUN gem source -r https://rubygems.org/ ---> Using cache ---> f58a08708863 Step 3 : RUN gem source -a http://gems.mydomain ---> Using cache ---> 3e69e17c5954 Step 4 : RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc ---> Using cache ---> 1edb37962dd4 Step 5 : RUN mkdir /foo ---> Running in 3d3441c34ee3 ---> aeb90f00bc9b Removing intermediate container 3d3441c34ee3 Step 6 : WORKDIR /foo ---> Running in 84b881d8f621 ---> 10e1d8984458 Removing intermediate container 84b881d8f621 Step 7 : RUN gem install bundler ---> Running in 31e98523ce46 Successfully installed bundler-1.6.2 1 gem installed ---> 84d5195ab831 Removing intermediate container 31e98523ce46 Step 8 : ADD Gemfile /foo/Gemfile ---> 3e5f2675ee22 Removing intermediate container c90e8be5ea17 Step 9 : RUN bundle install ---> Running in ac0e83e5eebb Fetching gem metadata from http://gems.mydomain/...... Fetching additional metadata from http://gems.mydomain/.. Resolving dependencies... Installing rake 10.3.2 Installing i18n 0.6.9 Installing multi_json 1.10.1 . . . Installing railties 3.2.19 Installing responders 0.9.3 Using bundler 1.6.2 Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. ---> 19beae703adb Removing intermediate container ac0e83e5eebb Step 10 : EXPOSE 8080 ---> Running in 1b1e55d349e5 ---> 32405bdac6d1 Removing intermediate container 1b1e55d349e5 Successfully built 32405bdac6d1 

git checkout B

git checkout A

dockerbuild设-t somename。

第二个build立日志

 Sending build context to Docker daemon 19.52 MB Sending build context to Docker daemon Step 0 : FROM myregistry:5000/ruby:2.1.2-1 ---> 9ce683a713b4 Step 1 : MAINTAINER ME ---> Using cache ---> 8f54114fd2e7 Step 2 : RUN gem source -r https://rubygems.org/ ---> Using cache ---> f58a08708863 Step 3 : RUN gem source -a http://gems.mydomain ---> Using cache ---> 3e69e17c5954 Step 4 : RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc ---> Using cache ---> 1edb37962dd4 Step 5 : RUN mkdir /foo ---> Using cache ---> aeb90f00bc9b Step 6 : WORKDIR /foo ---> Using cache ---> 10e1d8984458 Step 7 : RUN gem install bundler ---> Using cache ---> 84d5195ab831 Step 8 : ADD Gemfile /foo/Gemfile ---> 4977e35c80f7 Removing intermediate container bd59cc0d5e51 Step 9 : RUN bundle install ---> Running in 6ff16f32e94a Fetching gem metadata from http://gems.mydomain/...... Fetching additional metadata from http://gems.mydomain/.. Resolving dependencies... Installing rake 10.3.2 Installing i18n 0.6.9 Installing multi_json 1.10.1 . . . Installing railties 3.2.19 Installing responders 0.9.3 Using bundler 1.6.2 Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. ---> d9332f9035c3 Removing intermediate container 6ff16f32e94a Step 10 : EXPOSE 8080 ---> Running in b20252a00160 ---> 4d9932882e06 Removing intermediate container b20252a00160 Successfully built 4d9932882e06 

当文件的mtime值发生变化时,Docker使docker buildcaching失效,git不会跟踪文件的mtime值。 这种caching失效也会在其他情况下出现,就像持续集成或涉及Docker,Git和分支的构build环境一样。

在我要求docker构build一个容器之前,我一直在使用Makefile中的“touch”目标:

 touch: @echo "Reset timestamps on git working directory files..." find ./ | grep -v .git | xargs touch -t 200001010000.00 

接下来,在docker build之前或者在同一个Makefile中的任何基于docker的“构build”目标之前,始终运行make touch

另一个选项是设置一个自动修改mtime值的git钩子: https : //git.wiki.kernel.org/index.php/ExampleScripts#Setting_the_timestamps_of_the_files_to_the_commit_timestamp_of_the_commit_which_last_touched_them

另一个可能的解决scheme是fork docker并从其caching定义中移除mtime: https : //github.com/docker/docker/blob/master/pkg/tarsum/tarsum.go

注意 :从docker 1.8开始,在使caching无效时,不再考虑mtime 。 拉取请求#12031更新了此行为

git checkout,git clone,git fetch,等等修改文件的创builddate。 然后docker看到另一个文件,即使是相同的。

在创build文件更改date时,docker ADD命令无法caching。